正则表达式之贪婪匹配和非贪婪匹配(转)
原文: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(非贪婪匹配)。
总结
理解贪婪匹配和非贪婪匹配的区别对于编写准确的正则表达式至关重要。通过在量词后面添加 ? 可以轻松地将贪婪模式转换为非贪婪模式。在处理嵌套结构或需要精确匹配的情况下,非贪婪模式通常更为合适。通过上述示例,我们可以看到贪婪和非贪婪模式在不同场景下的应用和效果。