Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

${^MATCH} sometimes fails in target of substitution?

by raygun (Scribe)
on Jun 16, 2013 at 17:00 UTC ( [id://1039229]=perlquestion: print w/replies, xml ) Need Help??

raygun has asked for the wisdom of the Perl Monks concerning the following question:

Hello wise monks,

I'm unsure why these two lines produce different output. In particular, I don't know why the ${^MATCH} in the first line fails to be set to the matched part of the regular expression.
perl -e '$x = "abcde"; $x =~ s/b../==${^MATCH}==/p; print + "$x\n"' perl -e '$x = "abcde"; $sub="b.."; $x =~ s/$sub/==${^MATCH}==/p; print + "$x\n"'
Perl v5.12.4 produces:
a====e a==bcd==e
The perlre documentation gives no restrictions on contexts in which {^MATCH} can be used, saying only that it's an optimized synonym for $&. And in fact, if I change the first line to use $& instead of {^MATCH}, it behaves as expected. Thank you for any hints!

Replies are listed 'Best First'.
Re: ${^MATCH} sometimes fails in target of substitution?
by dave_the_m (Monsignor) on Jun 16, 2013 at 18:34 UTC
    It was a bug; fixed in 5.18.0.

    Dave.

Re: ${^MATCH} sometimes fails in target of substitution?
by space_monk (Chaplain) on Jun 16, 2013 at 17:38 UTC
    perlre states:
    As a workaround for this problem, Perl 5.10.0 introduces ${^PREMATCH} , ${^MATCH} and ${^POSTMATCH} , which are equivalent to $` , $& and $' , except that they are only guaranteed to be defined after a successful match that was executed with the /p (preserve) modifier.

    Update: The problem you have documented is a bug in releases prior to 5.18.See Re: ${^MATCH} sometimes fails in target of substitution?.

    Before 5.18 it appears that ${^MATCH} may only be available AFTER the match/replace. Adding print $(^MATCH} to your both example prints 'bcd' e.g.

    perl -e '$x = "abcde"; $x =~ s/b../==${^MATCH}==/p; prin +t "$x Match:${^MATCH}\n"' a====e Match:bcd perl -e '$x = "abcde"; $sub="b.."; $x =~ s/$sub/==${^MATCH}==/p; print + "$x Match:${^MATCH}\n"' a==bcd==e Match:bcd

    If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)

      If you're replacing, there was a successful match. This is a bug.

      Testing reveals this bug has been fixed:

      $ perl -v | grep 'This is' This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-li +nux-thread-multi $ perl -E'$_ = "abcde"; s/b../==${^MATCH}==/p; say' a====e $ perl -E'$_ = "abcde"; $sub="b.."; s/$sub/==${^MATCH}==/p; say' a==bcd==e
      $ perl -v | grep 'This is' This is perl 5, version 18, subversion 0 (v5.18.0) built for x86_64-li +nux-thread-multi $ perl -E'$_ = "abcde"; s/b../==${^MATCH}==/p; say' a==bcd==e $ perl -E'$_ = "abcde"; $sub="b.."; s/$sub/==${^MATCH}==/p; say' a==bcd==e

        Thanks, I amended my answer to reflect your comment and the earlier one of dave_the_m.

        If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)
Re: ${^MATCH} sometimes fails in target of substitution?
by farang (Chaplain) on Jun 16, 2013 at 18:10 UTC

    I think this has to do with optimization of the regexp. I may not be using terminology quite right, but Perl sees that the $sub variable can be interpolated, so the regexp is eval'd at compile time, thereby populating ${^MATCH}. That is, it is only after being eval'd once that ${^MATCH} gets the value from the search.

    The following code also forces a similar 'second eval'.

    my $x = "abcde"; $x =~ s/b../sprintf "==${^MATCH}=="/pe; print "$x\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1039229]
Approved by Happy-the-monk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2024-04-25 08:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found