正则表达式

当前位置:正则表达式 > 正则

正则表达式贪婪和非贪婪

什么是正则表达式的贪婪与非贪婪匹配

  如:String str="abcaxc";

    Patter p="ab*c";

  贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。

  非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。

下面通过实例代码看下正则表达式的贪婪模式与非贪婪模式,具体内容如下所示:

贪婪模式:能匹配的最大部分 

1
2
3
4
s = "This is a number 234-235-22-4223"
r = re.match(r"(.+)(\d+-\d+-\d+-\d+",s)
r.groups()
("This is a number 23","4-235-22-4223")

贪婪模式就是“.+”中的+会一直查找到最后一个符合条件的字符,所以上述代码中最前面的两个数字在提取数字是没有被提取到

非贪婪模式:匹配越少越好

1
2
3
4
s = "This is a number 234-235-22-4223"
r = re.match(r"(.+?)(\d+-\d+-\d+-\d+",s)
r.groups()
("This is a number ","234-235-22-4223")

非贪婪模式就是在“.+?"会匹配到第一个符合条件的字符就停止

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

>>> 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) 
 
 


相关文章
苏ICP备2022026517号-2  |   苏公网安备 32081202000316号
淮安先皓网络科技有限公司 © 版权所有  联系我们