使用正则表达式匹配 IP [重复]
Posted
技术标签:
【中文标题】使用正则表达式匹配 IP [重复]【英文标题】:Matching IP with Regex [duplicate] 【发布时间】:2014-02-05 19:52:24 【问题描述】:我正在尝试显示我的日志文件的日期时间和 IP 地址:
Apr 20 07:03:53 123.345.45.123
^ ^ ^ ^
|---datetime--| |-----IP-----|
我的代码:
datetimeRegex = re.compile(r'^\w3\s\d\d\s\d\d:\d\d:\d\d')
IPRegex = re.compile(r'\d+.\d+.\d+.\d1,3')
f = open("logfile.log","r")
count = 0
for line in f.readlines():
datetime = re.match(datetimeRegex, line)
IPaddr = re.match(IPRegex, line)
if datetime and IPaddr:
count += 1
print str(count) + ":" + str(datetime.group()) + "IP: " + str(IPaddr.group())
我试图查看不匹配的内容,我认为是 IPaddr
不匹配,因为我从 if 语句中删除了 IPaddr
并且我的输出将打印日期。当我添加IPaddr
时,什么都不会打印。所以我认为我没有正确匹配我的 IP 地址。但是,我在在线正则表达式测试仪上尝试了一个示例 IP 和我的正则表达式,它似乎有效。我的正则表达式中是否缺少某些内容?还是我的逻辑有问题?如果有更快或更有效的方式来解析日志文件,我愿意接受建议。
【问题讨论】:
我会检查一下谢谢! 您确定所有日期时间字符串都与您的日期/时间 RE 匹配吗?您的示例确实如此,但是所有这些看起来都像吗?假设你有Apr 1, 20:07:30
而不是Apr 01, 20:07:30
。在这种情况下,不匹配。
@mbratch 是的,我敢肯定,因为我一开始只测试了日期时间,并且所有的日期时间都在显示。当我包含 IPRegex 时,我得到 None 作为输出
【参考方案1】:
您应该使用re.search
而不是re.match
,因为re.match
只匹配行首,而re.search
将在字符串中的任何位置找到匹配项。
如果你稍微调整一下你的正则表达式也会更好(转义.
,它们是正则表达式中的通配符,并且匹配除换行符之外的所有内容,datetimeRegex 的不必要锚点,因为你将这个与re.match
一起使用,将\d\d?
用于匹配日期,例如Jan 1 12:34:56
和IP 正则表达式以接受更有效的IP)
datetimeRegex = re.compile(r'\w3\s\d\d?\s\d\d:\d\d:\d\d')
IPRegex = re.compile(r'\d1,3\.\d1,3\.\d1,3\.\d1,3')
# You can also use re.compile(r'(?:\d1,3\.)3\d1,3')
f = open("logfile.log","r")
count = 0
for line in f.readlines():
resdatetime = re.match(datetimeRegex, line) # And avoid using built-in names such as
# 'datetime'
IPaddr = re.search(IPRegex, line) # Here, use re.search
if resdatetime and IPaddr:
count += 1
print str(count) + ":" + str(datetime.group()) + "IP: " + str(IPaddr.group())
【讨论】:
我想过 IP 和 datetime 可能不在同一行,但在我的日志文件中,IP 地址实际上是一个远离 datetime 的空间,我总是认为一行是一组很长的字符 正如我在回答中的评论中指出的那样——这是因为他使用的是 re.match 而不是 re.search。 re.match 只有在字符串的开头与正则表达式匹配时才会匹配。 @adsmith 是的,成功了谢谢!! @Jerry 抱歉,我不知道很多内置的 python 函数,所以我想我的问题还不够清楚 @Liondancer Jerry 的困惑来自您的示例输入位于两行,而在您的程序中您希望它们位于一行。由于您正在遍历f.readlines()
,因此如果datetime
和IPAddr
在不同的行上,则永远不会出现匹配项。【参考方案2】:
用\.
替换所有.
的用法
单个句点是正则表达式中的特殊字符,表示“任何字符”。如果你想要一个文字句点,你需要使用\
字符来转义它。
IPRegex = re.compile(r"\d1,3\.\d1,3\.\d1,3\.\d1,3")
ip = "192.168.1.1"
matches = IPRRegex.match(ip)
[OUT] <_sre.SRE_Match object at 0x0000000003349578>
【讨论】:
我有这个re.compile(r'\d1,3\.\d1,3\.\d1,3\.\d1,3')
但没有输出=/
可能是因为您使用的 re.match
仅匹配行首。请改用re.search
,另见re.search() vs re.match()
以上是关于使用正则表达式匹配 IP [重复]的主要内容,如果未能解决你的问题,请参考以下文章