johngg has asked for the wisdom of the Perl Monks concerning the following question:
use strict; use warnings; use re q{eval}; sub doSep { print q{-} x 40, qq{\n}; } my $count = 0; my $string = q{<x1>[x2]{x3}(x4)}; my $rxClose = qr@[]>})]@; my $rxOpen = qr@[[<{(]@; my $rxBetween = qr {(?x) (?<=($rxClose)) (?=($rxOpen)) (?{print qq{Match @{ [++ $count] }: left $1, right $2\n}}) }; print qq{ Before: $string\n}; doSep(); $string =~ s{$rxBetween}{+}g; doSep(); print qq{ After: $string\n};
Even though the code block seems to execute twice per match the substitution is only done once. Here's the output, six apparent matches, weird.
Before: <x1>[x2]{x3}(x4) ---------------------------------------- Match 1: left >, right [ Match 2: left >, right [ Match 3: left ], right { Match 4: left ], right { Match 5: left }, right ( Match 6: left }, right ( ---------------------------------------- After: <x1>+[x2]+{x3}+(x4)
If I change the code so that look-arounds are not used the strange behaviour does not happen and the code block is only executed once per match.
use strict; use warnings; use re q{eval}; sub doSep { print q{-} x 40, qq{\n}; } my $count = 0; my $string = q{<x1>[x2]{x3}(x4)}; my $rxClose = qr@[]>})]@; my $rxOpen = qr@[[<{(]@; my $rxBetween = qr {(?x) ($rxClose) ($rxOpen) (?{print qq{Match @{ [++ $count] }: left $1, right $2\n}}) }; print qq{ Before: $string\n}; doSep(); $string =~ s{$rxBetween}{$1+$2}g; doSep(); print qq{ After: $string\n};
The output this time, just three matches as expected.
Before: <x1>[x2]{x3}(x4) ---------------------------------------- Match 1: left >, right [ Match 2: left ], right { Match 3: left }, right ( ---------------------------------------- After: <x1>+[x2]+{x3}+(x4)
I have done other testing to try and pin down what is happening. The code block also executes twice if I am just matching using look-arounds rather than substituting. I have also tried using just a single look-behind rather than both lokk-behind and -ahead but still get the double execution.
Can any Monk throw some light on what is happening here?
Cheers,
JohnGG
|
|---|