in reply to Regex: Overlapping Matches: Double Execution of Eval-ed Code

It is one of the things I consider to be a bug in Perl's regex engine. Zero-width matches can cause Perl to consider multiple matches starting at the same point. Perl eventually rejects identical matches in order to prevent an infinite loop. Your (?{ block catches Perl given a go at trying to match something different by trying the match a second time at each starting point.

You can work around this simply enough:

#!perl -wl use strict; my $s = 'abcd'; my @pairs1 = $s =~ m{ (?= (..)).? (?{ printf qq{ '$^N'} }) }xmsg; # ^^ print ''; printf qq{ :$_:} for @pairs1; print ''; my @pairs2 = $s =~ m{ (?= (..) (?{ printf qq{ '$^N'} })).? }xmsg; # ^^ print ''; printf qq{ :$_:} for @pairs2; print ''; __END__ 'ab' 'bc' 'cd' :ab: :bc: :cd: 'ab' 'bc' 'cd' :ab: :bc: :cd:

(Update: Pasted the wrong code for a few seconds.)

- tye        

  • Comment on Re: Regex: Overlapping Matches: Double Execution of Eval-ed Code (pos==pos && len!=len)
  • Download Code

Replies are listed 'Best First'.
Re^2: Regex: Overlapping Matches: Double Execution of Eval-ed Code (pos==pos && len!=len)
by AnomalousMonk (Archbishop) on Jan 15, 2012 at 21:46 UTC
    ... work around ...

    I, also, came up with a work-around similar to the JavaFan's, although whether better than yours is another question as it needs the Special Backtracking Control Verbs of 5.10+. This was in the course of fiddling with a reply to Re^5: dice's coefficient. The idea was to avoid list generation by the regex (and it also, coincidentally, works without the /g modifier), but the results were not particularly noteworthy in terms of speed.