貪婪與懶惰

鑑於以下輸入:

aaaaaAlazyZgreeedyAlaaazyZaaaaa

我們將使用兩種模式:一種是貪婪:A.*Z,一種是懶惰:A.*?Z。這些模式產生以下匹配:

  • A.*Z 產生 1 匹配:AlazyZgreeedyAlaaazyZ(例如: Regex101Rubular
  • A.*?Z 產生了 2 個匹配:AlazyZAlaaazyZ(例如: Regex101Rubular

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