The same regex does not match twice

Trying to solve the problem in my perl script, I could finally break it down into this situation:

my $content = 'test'; if($content =~ m/test/g) { print "1\n"; } if($content =~ m/test/g) { print "2\n"; } if($content =~ m/test/g) { print "3\n"; } 

Output:

 1 3 

My real business is a little different, but in the end it's the same thing: I'm confused why regex 2 is not suitable. Does anyone have an explanation? I realized that / g seems to be the cause, and of course this is not needed in my example. But (why) is this normal output behavior?

+5
source share
2 answers

This is exactly what /g should do in a scalar context.

The first time it matches the "test". The second match tries to start a match in the line after the previous match ended and ended in error. The third match then retries from the beginning of the line (and succeeds) because the second match failed and you did not specify /c either.

( /c does not allow you to restart it at the beginning, if the match fails, if your second match was /test/gc , the second and third matches will fail.)

+7
source

Generally speaking, if (/.../g) does not make sense and should be replaced by if (/.../) [1] .


You did not expect the following to match twice:

 my $content = "test"; while ($content =~ /test/g) { print(++$i, "\n"); } 

So why do you expect the following to match twice:

 my $content = "test"; if ($content =~ /test/g) { print(++$i, "\n"); } if ($content =~ /test/g) { print(++$i, "\n"); } 

They are the same!


Suppose $content contains testtest .

  • The first time $content =~ /test/g is evaluated in a scalar context, it corresponds to the first test .
  • The 2nd time $content =~ /test/g is evaluated in a scalar context, it corresponds to the second test .
  • For the 3rd time, $content =~ /test/g is evaluated in a scalar context, it returns false to indicate that there are no more matches.
    This also resets the position at which the $content matches will begin.
  • The 4th time $content =~ /test/g is evaluated in a scalar context, it corresponds to the first test .
  • ...

  • There are advanced options for using if (/\G.../gc) , but these are different. if (/.../g) only makes sense if you are if (/.../g) while loop. (for example, while (1) { ...; last if !/.../g; ... } ).
+7
source

Source: https://habr.com/ru/post/1260616/


All Articles