Is there any way to find out what was substituted for (the "old" text) after applying the s/// operator?  I tried doing:
if (s/(\w+)/new/) {
    my $oldTxt = $1;
    # ...
}
But that doesn't work. $1 is undefined.
Is there any way to find out what was substituted for (the "old" text) after applying the s/// operator?  I tried doing:
if (s/(\w+)/new/) {
    my $oldTxt = $1;
    # ...
}
But that doesn't work. $1 is undefined.
You should be able to use the Perl match variables:
$&Contains the string matched by the last pattern match
You could make the replacement an eval expression:
if (s/(\w+)/$var=$1; "new"/e) { .. do something with $var .. }
Your code works for me. Copied and pasted from a real terminal window:
$ perl -le '$_ = "*X*"; if (s/(\w+)/new/) { print $1 }'
X
Your problem must be something else.
$& does what you want but see the health warning in perlvar
The use of this variable anywhere in a program imposes a considerable performance penalty on all regular expression matches.
If you can find a way to do this without using $&, try that. You could run the regex twice:
my ($match) = /(\w+)/;
if (s/(\w+)/new/) {
    my $oldTxt = $match;
    # ...
}
If you're using 5.10 or later, you don't have to use the potentially-perfomance-killing $&. The ${^MATCH} variable from the /p flag does the same thing but only for the specified regex:
 use 5.010;
 if( s/abc(\w+)123/new/p ) {
      say "I replaced ${^MATCH}"
      }