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

时间:2016-12-01 00:19:55

标签: 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";
} 

输出:

1
3

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

2 个答案:

答案 0 :(得分:7)

这正是标量上下文中应该做的/g

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

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

答案 1 :(得分:7)

一般来说,if (/.../g)毫无意义,应该替换为if (/.../) [1]

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

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

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

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

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

他们是一样的!

我们假设$content包含testtest

  1. 第一次$content =~ /test/g在标量上下文中进行评估,它与第一次test匹配。
  2. 第二次$content =~ /test/g在标量上下文中进行评估,它与第二次test匹配。
  3. 第3次$content =~ /test/g在标量上下文中进行评估,它返回false表示没有更多匹配。
    这也会重置$content未来匹配的位置将开始。
  4. 第四次$content =~ /test/g在标量上下文中进行评估,它与第一次test匹配。
  5. ...
    1. if (/\G.../gc)有高级用途,但情况有所不同。 if (/.../g)只有在你展开while循环时才有意义。 (例如while (1) { ...; last if !/.../g; ... })。