贪婪与懒惰
鉴于以下输入:
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 正则表达式引擎没有惰性匹配。虽然重构,特别是 有史以来最伟大的技巧 ,在某些情况下可能有助于匹配,但真正的懒惰匹配的唯一方法是使用支持它的引擎。