相同的正则表达式不匹配两次

DOB*_*DOB 5 regex perl

试图解决我的perl脚本中的问题,我终于可以将其分解为这种情况:

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";
} 
Run Code Online (Sandbox Code Playgroud)

输出:

1
3
Run Code Online (Sandbox Code Playgroud)

我的实际情况略有不同,但最后却是同样的事情:我很困惑为什么正则表达式2不匹配.有人对此有解释吗?我意识到/ g似乎是原因,当然这在我的例子中并不需要.但(为什么)这个输出正常行为?

yst*_*sth 7

这正是/g标量上下文应该做的事情.

第一次匹配"测试".第二个匹配尝试在上一个匹配关闭后的字符串中开始匹配,并失败.然后第三个匹配从字符串的开头再次尝试(并且成功)因为第二个匹配失败而您也没有指定/c.

(/c如果匹配失败,则阻止它在开始时重新启动;如果第二次匹配/test/gc,则第二次和第三次匹配都会失败.)

  • @ ssr1012`c - 在重复匹配期间保持当前位置 (2认同)

ike*_*ami 7

一般来说,if (/.../g)没有意义,应该用if (/.../)[1]代替.


您不希望以下内容匹配两次:

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

那么为什么你希望以下两次匹配:

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

if ($content =~ /test/g) {
   print(++$i, "\n");
}
Run Code Online (Sandbox Code Playgroud)

他们是一样的!


让我们想象$content包含testtest.

  1. 第一次$content =~ /test/g在标量上下文中进行评估,
    它与第一次匹配test.
  2. 第二次$content =~ /test/g在标量上下文中进行评估,
    它与第二次匹配test.
  3. 第三次$content =~ /test/g在标量上下文中计算,
    它返回false表示没有更多匹配.
    这也会重置$content未来比赛开始的位置.
  4. 第四次$content =~ /test/g在标量上下文中进行评估,
    它与第一次匹配test.
  5. ...

  1. 有先进的用途if (/\G.../gc),但这是不同的.if (/.../g)只有在你展开while循环时才有意义.(例如while (1) { ...; last if !/.../g; ... }).