in reply to Re: weird regex problem
in thread weird regex problem
Right fix davorg, but wrong explanation :). Here is the relevant code section again:
if ( $contents =~ /line3/g ) { if ( $contents =~ /(line2-)(\w*)/g ) { print $2; } }
In $contents is the slurped file:
line1-11
line2-12
line3-13
The first if matches
'line3' and returns true. The second match picks up at the
position where the first match left (because it has also the
/g modifier) and fails (!) because line2 is before line3.
So removing the /g modifier on the second 'if' solves the
problem as the match is now done from the start of $contents.
As a matter of fact, the /g modifier can be left out for
both matches.
Some further optimisations I would suggest for this
regex:
if ( $contents =~ /^line3/mo ) { if ( $contents =~ /^line2-(\w*)/mo ) { print $1; # has to be changed as well } }
To clarify the /g modifier a little bit further let's take a look at this code (of course see also perlre and perlop):
my $string = "abcde abcde adcde"; while ($string =~ /cd/og) { print "pos = ", pos $string, "\n"; if ($string =~ /a(.)/ocg) { print "a$1 matched at ",pos $string, "\n"; } }
Here the first match happens in a while loop, but important still in scalar context. The inner matching starts at the position where the first left off as it also has the /g modifier. Then the outer match takes its turn again starting where the inner left off. The position in the string is only reset when a match fails. This does not happen when the /c modifier is given. This is necessary for the second match in this case - otherwise there is an infinite loop.
Taking this code and playing a bit with the modifiers and the string helps a lot in understanding these (not so easy) things. And I haven't even started talking about m//g in list context yet ...
-- Hofmator
|
|---|