繁体   English   中英

为什么re.findall()找到比re.sub()更多的匹配?

[英]Why does re.findall() find more matches than re.sub()?

考虑以下:

>>> import re
>>> a = "first:second"
>>> re.findall("[^:]*", a)
['first', '', 'second', '']
>>> re.sub("[^:]*", r"(\g<0>)", a)
'(first):(second)'

re.sub()的行为最初更有意义,但我也能理解re.findall()的行为。 毕竟,你可以匹配firstfirst一个之间的空字符串:它只包含非冒号字符(正好是零),但为什么re.sub()行为方式不同?

不应该是最后一个命令的结果是(first)():(second)()

你使用允许空匹配的*:

'first'   -> matched
':'       -> not in the character class but, as the pattern can be empty due 
             to the *, an empty string is matched -->''
'second'  -> matched
'$'       -> can contain an empty string before,
             an empty string is matched -->''

引用re.findall()文档

结果中包含空匹配,除非它们触及另一个匹配的开头。

您在子结果中看不到空匹配的原因在re.sub()文档中进行了解释:

仅当与前一个匹配不相邻时,才会替换模式的空匹配。

尝试这个:

re.sub('(?:Choucroute garnie)*', '#', 'ornithorynque') 

现在这个:

print re.sub('(?:nithorynque)*', '#', 'ornithorynque')

没有连续的#

由于某种原因,处理空匹配的算法是不同的。

findall的情况下,它的工作方式类似于(优化版本):对于每个可能的起始索引0 <= i <= len(a),如果字符串在i处匹配,则追加匹配; 并且通过使用此规则避免重叠结果:如果在i处存在长度为m的匹配,则不要在i + m之前查找下一个匹配项。 你的例子返回['first', '', 'second', '']是在firstsecond之后立即找到空匹配,但不是在冒号之后找到 - 因为从那个位置开始寻找一个匹配返回完整的字符串second

sub的情况下,正如您所注意到的那样,区别在于它明确忽略了在另一个匹配之后立即发生的长度为0的匹配。 虽然我明白为什么这可能有助于避免出现意外行为sub ,我不确定为什么会存在这种差异(例如,为什么不findall使用相同的规则)。

import re
a = "first:second:three"
print re.findall("[^:]*", a)

返回匹配模式的所有子字符串,这里给出

>>> 
['first', '', 'second', '', 'three', '']

sub()用于替换,并将替换最左边的非重叠模式。

import re
a = "first:second:three"
print re.sub("[^:]*", r"smile", a)

>>> 
smile:smile:smile

您可以使用第4个arg命令要替换的出现次数,count:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM