正则表达式贪婪与非贪婪模式

2022年6月8日14:05:44

高级用法在这里:正则表达式(三)——高级用法:search,findall,sub,split

8.贪婪与非贪婪模式

首先我们以简单的例子来说说什么是正则表达式的贪婪与非贪婪匹配

比如假定匹配字符串和正则表达式为:

>>> match_str = 'abcdefc'  #匹配字符串
  •  贪婪匹配:
>>> pattern = r'ab.*c'
>>> re.match(pattern,match_str)
<_sre.SRE_Match object; span=(0, 7), match='abcdefc'>

 正则表达式一般趋向于最大长度匹配,总是尝试匹配尽可能多的字符,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcdefc。当出现c时,它还是继续向后找,又找到c,它就把cdef当做是(.*)的匹配

  • 非贪婪匹配
>>> pattern = r'ab.*?c'  #非贪婪匹配
>>> re.match(pattern,match_str)
<_sre.SRE_Match object; span=(0, 3), match='abc'>

非贪婪匹配就是匹配到结果就好,总是尝试匹配尽可能少的字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc。当它遇见c后,它就停止查找,此时把空字符作为(.*)的匹配。

那么贪婪与非贪婪怎么区分呢?

re模块默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。

我们熟知的量词有:

* 任意多个
+ 至少一个
0或1个
{m,n} m到n个

在上一节中的去除HTML中的标签时,我们使用r'<.+>'去匹配得到的却是一堆'\n',我们来看看原因。拿其中的一行来看,为什么输出'\n':

<p><br/></p>

 分析:sub函数先做匹配操作,再做替换操作。在匹配操作时,首先匹配 <(左尖括号),<p>的<就已经匹配到,当匹配到<p>的>时,匹配未结束,它继续往后匹配。当匹配到<br/>的>时,仍然未结束,贪婪的向后继续匹配,直到匹配到</p>的>,再继续去匹配,字符串后面有个‘\n',结束匹配,它就把  p><br/></p 这些内容都当做 .+ 来处理。因此匹配到这一行内容除了'\n',并进行替换操作,替换为空字符'',因此输出'\n'。因此,在 .+ 后面加上?表示非贪婪模式,当碰到<p>的 > 就停止此次匹配。

>>> re.sub(r'<.+?>','',s)

至此,正则表达式的学习就告一段落了,还是需要在实践中才能检验出真理......

  • 作者:虾米儿xia
  • 原文链接:https://blog.csdn.net/m0_37673307/article/details/81631880
    更新时间:2022年6月8日14:05:44 ,共 1021 字。