re.findall()的格式输出

时间:2019-04-08 14:37:52

标签: python regex format

我试图过滤在access.log(已读入并转换为字符串)中找到的每个IP地址,然后计算它们的出现次数。我可以这样做,但是列表中IP地址的格式很奇怪。列表中的一个元素是“('110','78','168','85')”,而不是“('110.78.168.85')”。如何使它看起来像IP地址?

我试图阅读有关Stackoverflow的其他答案,但似乎没有一个能解决我的问题。

import re


f = open("/var/log/apache2/access.log", "r")
f_as_string = f.read()
f.close()

x = re.findall(r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', f_as_string)

# ...
('110.78.168.85') 

代替

('110', '78', '168', '85')

1 个答案:

答案 0 :(得分:1)

findall将返回组列表,如果您的模式中有任何捕获组。您的模式有四对括号,因此findall返回一个包含四元素元组的列表。

尝试使用非捕获括号编写模式。

>>> import re
>>> f_as_string = "foobar 110.78.168.85 bazqux 123.45.067.89"
>>> re.findall(r'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', f_as_string)
['110.78.168.85', '123.45.067.89']

或者,保持正则表达式模式不变,并使用finditer从匹配对象中仅提取完整的组。

>>> import re
>>> f_as_string = "foobar 110.78.168.85 bazqux 123.45.067.89"
>>> [m.group() for m in re.finditer(r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', f_as_string)]
['110.78.168.85', '123.45.067.89']