#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2012
    Posts
    62
    Rep Power
    3

    $MATCH not working like $`


    Hi, as per the Perlvar manpage, the $PREMATCH variable (alongwith @- and @+ arrays) was meant to do the same thing as $` without the performance overload of the latter. However, when I try the following code:

    Code:
    $a = "abc123dfv";
    if ($a =~ m/\d+/) {
    print "Yep: $PREMATCH \n";
    }
    Nothing gets printed after Yep:, whereas if I run this:

    Code:
    $a = "abc123dfv";
    if ($a =~ m/\d+/) {
    print "Yep: $` \n";
    }
    I get the usual result: Yep: abc. Can anybody explain it?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2007
    Posts
    765
    Rep Power
    928
    Originally Posted by perldoc perlvar
    ...if you wish to use long variable names, you need only say:
    use English;
    Also, $PREMATCH is $`. All performance penalties with using $` apply to $PREMATCH. The way to avoid the performance hit is to emulate it using @- and substr, or to use the /p modified where needed and the ${^PREMATCH} variable.
    sub{*{$::{$_}}{CODE}==$_[0]&& print for(%:: )}->(\&Meh);
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    It does not appear that you are running under strictures or warnings, meaning that you are missing these lines.
    Code:
    use strict;
    use warnings;
    Do you have this line in you script?
    Code:
    use English;
    The lack of those 3 lines would explain why you're having this problem.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2012
    Posts
    62
    Rep Power
    3
    Thanks. Can someone give an example showing how to use ${^PREMATCH}?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use English;
    
    my $str = "abc123dfv";
    
    if ($str =~ m/\d+/) {
        print "Yep: ${^PREMATCH}\n";
    }
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2012
    Posts
    62
    Rep Power
    3
    What about the /p modifier Omegazero mentioned? And why two variables like $MATCH and ${^MATCH} do the same thing?
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    The /p modifier is not required, but probably should be used. The few tests I made did not make any difference with/without the use of /p.

    $MATCH and ${^MATCH} are not doing the same thing, but they do return the same value. More correctly, they are using different methods to preform the same task.

    Have you read all of the related sections of perlvar? What portion of that info do you not understand?
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2012
    Posts
    62
    Rep Power
    3
    No no, it's clear now. Thanks!
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2007
    Posts
    765
    Rep Power
    928
    Originally Posted by FishMonger
    The /p modifier is not required, but probably should be used.
    Code:
    $txt = "abc123xyz";
    if ($txt =~ m/\d+/) {
        $txt = "xyz123abc";
        print "Prematch: ${^PREMATCH} \n";
    }
    
    $txt = "abc123xyz";
    if ($txt =~ m/\d+/p) {
        $txt = "xyz123abc";
        print "Prematch: ${^PREMATCH} \n";
    }
    Code:
    C:\temp>perl test2.pl
    Prematch: xyz
    Prematch: abc
    The behavior of ${^PREMATCH} without using /p is unspecified. In the current version of perl, it seems to degenerate into substr($string,0,@-[0]). The docs don't say it should work like that, or that it will work like that in the future, so use /p and your script won't mysteriously break in the future.
    sub{*{$::{$_}}{CODE}==$_[0]&& print for(%:: )}->(\&Meh);
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    I was not able to reproduce that discrepancy using your example, which shows the unpredictable nature of not using /p in this case.

    c:\testing>prematch.pl
    Prematch: abc
    Prematch: abc

IMN logo majestic logo threadwatch logo seochat tools logo