这个问题在这里已有答案:
我正在尝试过滤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')
如果您的模式有任何捕获组,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']