对于学校我应该写一个提取IP地址的Python RE脚本.我正在使用的正则表达式似乎可以使用re.search()但不能使用re.findall().
exp = "(\d{1,3}\.){3}\d{1,3}"
ip = "blah blah 192.168.0.185 blah blah"
match = re.search(exp, ip)
print match.group()
Run Code Online (Sandbox Code Playgroud)
对此的匹配总是192.168.0.185,但它与我的不同 re.findall()
exp = "(\d{1,3}\.){3}\d{1,3}"
ip = "blah blah 192.168.0.185 blah blah"
matches = re.findall(exp, ip)
print matches[0]
0.
Run Code Online (Sandbox Code Playgroud)
我想知道为什么re.findall()收益率为0.当re.search()收益率为192.168.0.185时,因为我对两个函数使用相同的表达式.
我能做些什么来实现它re.findall()才能真正遵循正确的表达方式?还是我犯了某种错误?
Kru*_*Kru 14
findall 返回匹配列表,并从文档中:
如果模式中存在一个或多个组,则返回组列表; 如果模式有多个组,这将是一个元组列表.
因此,您之前的表达式有一个组在最后一个匹配的字符串中匹配3次 0.
要解决您的问题,请使用: exp = "(?:\d{1,3}\.){3}\d{1,3}"; 通过使用非分组版本,没有返回的组,因此在两种情况下都返回匹配.
您只捕获该正则表达式中的 0,因为它将是最后捕获的。
更改表达式以捕获整个IP,并将重复部分作为非捕获组:
In [2]: ip = "blah blah 192.168.0.185 blah blah"
In [3]: exp = "((?:\d{1,3}\.){3}\d{1,3})"
In [4]: m = re.findall(exp, ip)
In [5]: m
Out[5]: ['192.168.0.185']
In [6]:
Run Code Online (Sandbox Code Playgroud)
如果它有助于解释正则表达式:
In [6]: re.compile(exp, re.DEBUG)
subpattern 1
max_repeat 3 3
subpattern None
max_repeat 1 3
in
category category_digit
literal 46
max_repeat 1 3
in
category category_digit
Run Code Online (Sandbox Code Playgroud)
这解释了子模式。子模式 1 是 findall 捕获的内容。