Regular expression – Why does this frontal assertion does not work when anchored to the beginning of a string?

Why does this post-assertion not work when it is fixed at the front of the string? Run the following code, and you will see that the first test passes, but the second test only passes the ^ anchor point change, but fails.

use Test: :More tests => 2;

my $s ='/123/456/hello';
$s =~ s{(?<=/)\d+(?=/ \d+/hello)}{0}; # unanchored
is($s,'/0/456/hello','unanchored'); # passes

$s ='/ 123/456/hello';
$s =~ s{^(?<=/)\d+(?=/\d+/hello)}{0}; # anchored
is($s ,'/0/456/hello','anchored'); # fails

Moving ^ into the backsight assertion is not an option for me (this is an extremely simplified example), but it does solve it I found another way to do what I want, but I’m curious why this method doesn’t work. I tested it on perl 5.8.8 and perl 5.10.0.

Please remember that the assertion is zero width and will not consume the characters it matches. So the anchor must enter the assertion, otherwise The entire expression does not match.

Why does this post-assertion not work when it is fixed at the front of the string? Run the following code, and you will see that the first test passes, but the second test only passes the ^ anchor point change, but fails.

use Test: :More tests => 2;

my $s ='/123/456/hello';
$s =~ s{(?<=/)\d+(?=/ \d+/hello)}{0}; # unanchored
is($s,'/0/456/hello','unanchored'); # passes

$s ='/ 123/456/hello';
$s =~ s{^(?<=/)\d+(?=/\d+/hello)}{0}; # anchored
is($s ,'/0/456/hello','anchored'); # fails

Moving ^ into the backsight assertion is not an option for me (this is an extremely simplified example), but it does solve it I found another way to do what I want, but I’m curious why this method doesn’t work. I tested it on perl 5.8.8 and perl 5.10.0.

Please remember that the assertion is zero width and will not consume the characters it matches. So the anchor must enter the assertion, otherwise the entire expression will not match.

Leave a Comment

Your email address will not be published.