正則表達式之貪婪匹配和非貪婪匹配(轉)
原文:https://blog.csdn.net/wang15510689957/article/details/145266869
作者:計算機學長大白
在正則表達式中,貪婪匹配(Greedy Matching)和非貪婪匹配(Non-Greedy Matching)是兩種不同的匹配策略,它們決定了正則表達式引擎在匹配時的行為。
「貪婪匹配」:默認情況下,正則表達式是貪婪匹配的,這意味著它會盡可能多地匹配字符。例如,在字符串 "aaaa" 中使用正則表達式 a*,貪婪匹配會匹配整個字符串 "aaaa"。
「非貪婪匹配」:非貪婪匹配(也稱為惰性匹配)則盡可能少地匹配字符。在字符串 "aaaa" 中使用正則表達式 a*?,非貪婪匹配只會匹配空字符串,因為它是盡可能少地匹配。
如何在Python中使用貪婪匹配和非貪婪匹配
在Python中,可以通過在量詞(如 *, +, ?, {m,n})后面添加 ? 來實現非貪婪匹配。具體來說:
*?:匹配前面的元素零次或多次,但盡可能少地匹配。
+?:匹配前面的元素一次或多次,但盡可能少地匹配。
??:匹配前面的元素零次或一次,但盡可能少地匹配。
{m,n}?:匹配前面的元素至少 m 次,但不超過 n 次,盡可能少地匹配。
示例
示例1:基本的貪婪與非貪婪匹配
import re text = "aabcdaaabbb" # 貪婪匹配 greedy_match = re.match(r"a.*b", text) if greedy_match: print("貪婪匹配:", greedy_match.group()) # 輸出: 貪婪匹配: aabcdaaabbb # 非貪婪匹配 non_greedy_match = re.match(r"a.*?b", text) if non_greedy_match: print("非貪婪匹配:", non_greedy_match.group()) # 輸出: 非貪婪匹配: aab
在這個例子中,a.*b 會匹配從第一個 a 開始到最后一個 b 結束的所有字符(貪婪匹配),而 a.*?b 則只會匹配從第一個 a 開始到第一個 b 結束的最短字符串(非貪婪匹配)。
示例2:處理嵌套結構
在處理嵌套結構時,非貪婪匹配特別有用。例如,從HTML字符串中提取標簽內的文本:
import re html = "<section><p>Hello</p></section>" # 貪婪匹配 greedy_regex = re.compile(r"<.*>") greedy_match = greedy_regex.search(html) if greedy_match: print("貪婪匹配:", greedy_match.group()) # 輸出: 貪婪匹配: <section><p>Hello</p></section> # 非貪婪匹配 non_greedy_regex = re.compile(r"<.*?>") non_greedy_match = non_greedy_regex.search(html) if non_greedy_match: print("非貪婪匹配:", non_greedy_match.group()) # 輸出: 非貪婪匹配: <section>
在這個例子中,<.*> 會匹配整個字符串 <section><p>Hello</p></section>(貪婪匹配),而 <.*?> 只會匹配 <section>(非貪婪匹配)。
示例3:匹配數字
假設我們要從字符串中提取數字:
import re s = "hello 1234567 world" # 貪婪匹配 greedy_match = re.match(r'he.*(\d+).*rld$', s) if greedy_match: print("貪婪匹配:", greedy_match.group(1)) # 輸出: 貪婪匹配: 7 # 非貪婪匹配 non_greedy_match = re.match(r'he.*?(\d+).*rld$', s) if non_greedy_match: print("非貪婪匹配:", non_greedy_match.group(1)) # 輸出: 非貪婪匹配: 1234567
在這個例子中,he.*(\d+).*rld$ 會匹配到 7(貪婪匹配),而 he.*?(\d+).*rld$ 會匹配到 1234567(非貪婪匹配)。
總結
理解貪婪匹配和非貪婪匹配的區別對于編寫準確的正則表達式至關重要。通過在量詞后面添加 ? 可以輕松地將貪婪模式轉換為非貪婪模式。在處理嵌套結構或需要精確匹配的情況下,非貪婪模式通常更為合適。通過上述示例,我們可以看到貪婪和非貪婪模式在不同場景下的應用和效果。

浙公網安備 33010602011771號