tags:

views:

119

answers:

5

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.

A: 

You should be able to use the Perl match variables:

$& Contains the string matched by the last pattern match

ennuikiller
A: 

You could make the replacement an eval expression:

if (s/(\w+)/$var=$1; "new"/e) { .. do something with $var .. }
crazyscot
While this would work, there's no need for it. The code he posted is correct as-is.
cjm
+7  A: 

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.

Sean
maybe his expression did not match, then no substitution occur and $1 is not set.
kriss
if it did not match then it would not even get into the body of the "if"
JoelFan
@JoelFan: My guess is that you simplified the code in order to post it here, and in doing so removed whatever the bug was.
cjm
+1  A: 

$& 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;
    # ...
}
Philip Potter
+6  A: 

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}"
      }
brian d foy