正则表达式中的 (.)+ 是什么行为?

6
我们在某些代码中发现了一个 bug,程序员使用了等价于 (.)+ 的表达式,但实际上应该使用 (.+)。这是一个很容易修复的问题,但我们无法解释为什么 (.)+ 匹配到了正则表达式中字母 "a" 后面的第一个字母 "e" 而不是 "b"。有谁能够解释一下为什么会出现这种情况?另外,如何解释 (.)+ 这个表达式?
my $s = 'abcde';

if ($s =~ m{ a (.)+  }x ){
    print "s '$s' matched '$1'\n";
}else{
    print "total match fail\n";
}

__END__
output:
s 'abcde' matched 'e'

1
我相信这背后的原因是因为它会一直匹配,直到无法匹配为止。在这个时候,最后一个匹配的字符就会被捕获到组里面。 - Peter O'Callaghan
1
尝试在你的代码顶部添加use re 'debug';。这对于跟踪正在发生的情况非常有用。 - Sobrique
4
我喜欢 Repeating a Capturing Group vs. Capturing a Repeated Group 的解释。 - ThisSuitIsBlackNot
@Sobrique(哎呀,不小心删掉了)这是我的第一反应,但在这种情况下并没有什么启示作用,即使你已经知道发生了什么。 - ThisSuitIsBlackNot
1个回答

10

在捕获的内容方面,(.)+(.+) 有很大的区别,但在匹配的内容方面则没有。

(.)+ 寻找单个字符的一个或多个 实例 并捕获最后一个实例。

(.+) 寻找一个或多个单个字符并一次性捕获它们全部。


我不知道 (.)+ 的文档/安全程度如何。 我会使用 (.)* - ikegami
3
不应该是 .*(.) 吗? - AnFi
@Andrzej A. Filip,哎呀!是的,我指的是.*(.) - ikegami
“captures the last of these”,是的,这也是我们得出的结论。 - Kevin G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接