贪婪与懒惰
鉴于以下输入:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
我们将使用两种模式:一种是贪婪:A.*Z,一种是懒惰:A.*?Z。这些模式产生以下匹配:
A.*Z产生 1 匹配:AlazyZgreeedyAlaaazyZ(例如: Regex101 , Rubular )A.*?Z产生了 2 个匹配:AlazyZ和AlaaazyZ(例如: Regex101 , Rubular )
首先关注 A.*Z 的作用。当它与第一个 A 匹配时,.*,贪婪,然后尝试匹配尽可能多的 .。
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\________________________/
A.* matched, Z can't match
由于 Z 不匹配,引擎回溯,然后 .*必须匹配少一个 .:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\_______________________/
A.* matched, Z can't match
这种情况发生了几次,直到它最终出现:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\__________________/
A.* matched, Z can now match
现在 Z 可以匹配,所以整体模式匹配:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\___________________/
A.*Z matched
相比之下,A.*?Z 中的不情愿(懒惰)重复首先匹配尽可能少的 .,然后根据需要采取更多的 .。这解释了为什么它在输入中找到两个匹配项。
这是两种模式匹配的直观表示:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\____/l \______/l l = lazy
\_________g_________/ g = greedy
基于实例的答案所作 polygenelubricants 。
POSIX 标准不包括 ? 运算符,因此许多 POSIX 正则表达式引擎没有惰性匹配。虽然重构,特别是 有史以来最伟大的技巧 ,在某些情况下可能有助于匹配,但真正的懒惰匹配的唯一方法是使用支持它的引擎。