📜  非贪婪的正则表达式 (1)

📅  最后修改于: 2023-12-03 15:28:53.057000             🧑  作者: Mango

非贪婪的正则表达式

什么是非贪婪的正则表达式?

在正则表达式中,*、+、?、{m,n}这些量词默认都是贪婪的,也就是匹配尽可能多的字符,直到不能匹配为止。例如,在字符串"abcdefg"中,匹配"a.g"会得到"abcdefg",而匹配"a.?g"则会得到"ab"。

非贪婪的正则表达式,也就是懒惰匹配,可以尽可能少地匹配字符,直到满足条件为止。在元字符后面加上"?"可以实现非贪婪匹配。例如,在字符串"abcdefg"中,匹配"a.*?g"会得到"abg"。

使用方法

在正则表达式中,对于量词"*"、"+"、"?"、"{m,n}",我们可以在后面加上"?",表示开启非贪婪模式。例如:

  • ".*?"表示匹配任意字符,但是尽可能少地匹配
  • ".+?"表示匹配至少一个字符,但是尽可能少地匹配
  • ".{3,5}?"表示匹配3到5个字符,但是尽可能少地匹配
  • "??"表示匹配0或1个字符,但是尽可能少地匹配
  • "*?"表示匹配0到多个字符,但是尽可能少地匹配
  • "+?"表示匹配至少一个字符,但是尽可能少地匹配

举个例子,在匹配HTML标签时,我们可以使用非贪婪模式避免匹配到多个标签。例如:

>>> import re
>>> s = '<div>foo</div><div>bar</div>'
>>> re.findall(r'<div>.*?</div>', s)
['<div>foo</div>', '<div>bar</div>']
>>> re.findall(r'<div>.*</div>', s)
['<div>foo</div><div>bar</div>']
注意事项

虽然非贪婪匹配可以避免过多匹配,但是在某些情况下,它可能会导致性能下降。因为非贪婪匹配会尝试匹配每一个字符,直到满足条件为止,因此比贪婪匹配更耗时。在处理大量数据时,应该谨慎使用非贪婪匹配。

另外,在使用非贪婪匹配时,需要注意它的优先级。例如,在正则表达式"abc.*?def|abc.*def"中,"abc.def"会优先于"abc.?def"匹配,因为"abc.*def"的优先级更高。因此,在实际使用中,我们需要根据具体情况调整正则表达式的结构,以便得到正确的匹配结果。

总结

非贪婪匹配是正则表达式中非常有用的一种技巧,可以避免过多匹配字符,提高匹配效率。在使用时,需要注意它的优先级和性能问题,根据具体情况进行调整。