对于学校,我应该编写一个提取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()
该匹配始终为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.
我想知道为什么re.findall()
得到0. re.search()
得到192.168.0.185,因为我对两个函数使用相同的表达式。
我能做些什么来使re.findall()
实际上正确地遵循表达式?还是我犯了某种错误?
答案 0 :(得分:13)
findall
返回匹配列表,并从文档中
如果模式中存在一个或多个组,则返回a 小组名单;如果模式,这将是一个元组列表 有不止一个小组。
因此,您之前的表达式中有一个组在字符串中匹配3次,其中最后一个匹配为0.
要解决您的问题,请使用:exp = "(?:\d{1,3}\.){3}\d{1,3}"
;通过使用非分组版本,没有返回的组,因此在两种情况下都会返回匹配。
答案 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]:
如果它有助于解释正则表达式:
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
这解释了子模式。子模式1是findall捕获的内容。