貪婪與懶惰
鑑於以下輸入:
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 正規表示式引擎沒有惰性匹配。雖然重構,特別是 有史以來最偉大的技巧 ,在某些情況下可能有助於匹配,但真正的懶惰匹配的唯一方法是使用支援它的引擎。