为什么re.findall与re.search相比表现怪异

时间:2019-05-15 18:39:06

标签: python-3.x

方案1:按预期工作

>>> output = 'addr:10.0.2.15'
>>> regnew = re.search(r'addr:(([0-9]+\.){3}[0-9]+)',output)
>>> print(regnew)
<re.Match object; span=(0, 14), match='addr:10.0.2.15'>
>>> print(regnew.group(1))
10.0.2.15

方案2:按预期工作

>>> regnew = re.findall(r'addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)',output)
>>> print(regnew)
['10.0.2.15']

方案3:无法按预期方式工作。为什么输出不是['10 .0.2.15']?

>>> regnew = re.findall(r'addr:([0-9]+\.){3}[0-9]+',output)
>>> print(regnew)
['2.']

2 个答案:

答案 0 :(得分:0)

您的正则表达式与您想要的不正确:

import re
output = 'addr:10.0.2.15'
regnew = re.findall(r'addr:((?:[0-9]+.){3}[0-9]+)', output)
print(regnew)

请注意,更改之处在于我用括号将完整的IP地址包裹起来,并在地址的第一部分添加了“?:”。 '?:'表示它是non capturing group。文档中所述的findall()给出了已捕获组的列表,这就是为什么您希望将'(?:[0-9] +。)'作为未捕获组,并且希望将整个内容包含在其中一个小组。

答案 1 :(得分:0)

findall和其他所有内容之间的区别在于,findall默认情况下返回捕获组(如果存在)而不是整个匹配的表达式。

一种快速的解决方法是将重复的组简单地更改为非捕获组,因此findall将返回完全匹配项,而不是捕获组中的最后一个结果。

addr:(?:[0-9]+\.){3}[0-9]+

当然,您的比赛中将包括addr:。要仅获取IP地址,请将模式和量词都包装在捕获组中。

addr:((?:[0-9]+\.){3}[0-9]+)