为什么 a*a 匹配 aaa?

Why does a*a match aaa?

我正在使用 python3 re 模块 - 我发现 a*a 匹配 aaa。我认为正则表达式在默认情况下是贪婪的(除非我们用 ? 将其覆盖为惰性) - 所以,a* 会匹配整个字符串,并且模式中的尾随 a 会失败。但是,它匹配:

$ import re
$ re.match(r'a*a', 'aaa')
<_sre.SRE_Match object; span=(0, 3), match='aaa'>

这应该不会失败吗?

最初尝试匹配整个字符串,但如果匹配失败,重复将回溯a* 初始匹配整个字符串后,正则表达式尝试匹配下一个标记,单个 a 失败,因此 a* backtracks 返回一个字符(这样它只匹配 aa 而不是 aaa)。这一次,最后一个标记,单个 a 满足,因此找到了匹配项。

贪婪并不意味着正则表达式只有在允许重复标记匹配字符串的整个其余部分时才会匹配。如果可以,它,如果不能,它会回溯。

即使 * 的贪婪重复回溯到零长度,也没有问题,因为 * 意味着匹配 零次或更多 次。 (相比之下,用 + 重复,如果回溯到零长度,正则表达式将完全失败,因为 + 意味着 至少有一个重复 必填)

a* 表示零个或多个 "a" 个字符。 a*a 表示“零个或多个 "a" 个字符后跟一个 "a"。"aaa" 确实是“零个或多个字符后跟一个 "a" 因为 "aa"满足"zero or more"的条件。