python3:从编译模式中提取IP地址

2024-09-27 00:20:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我想处理日志文件中的每一行,并提取IP地址(若行匹配我的模式)。有几种不同类型的消息,在下面的示例中,我使用p1andp2`。在

我可以逐行读取文件,并且每行都与每个模式相匹配。但是 我希望能有更多的模式。我希望将这些模式编译成一个对象,并且每行只匹配一次:

import re

IP = r'(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'

p1 = 'Registration from' + IP + '- Wrong password' 
p2 = 'Call from' + IP + 'rejected because extension not found'

c = re.compile(r'(?:' + p1 + '|' + p2 + ')')

for line in sys.stdin:
    match = re.search(c, line)
    if match:
        print(match['ip'])

但是上面的代码不起作用,它抱怨ip被使用了两次。在

实现我的目标最优雅的方式是什么?在

编辑:

我根据@Dev Khadka的回答修改了我的代码。在

但我仍然在努力解决如何正确处理多个ip匹配。下面的代码将打印与p1匹配的所有IP:

^{pr2}$

但是有些行与p1不匹配。它们匹配p2。也就是说,我得到:

^{3}$

当我不知道是p1p2p2时,如何打印匹配的ip?我只想要IP。我不在乎它和哪个图案匹配。在


Tags: 文件代码fromipre消息示例类型
3条回答

这是因为你对两个组使用相同的组名

试试这个,这将给出组名ip1和ip2

import re

IP = r'(?P<ip%d>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'

p1 = 'Registration from' + IP%1 + '- Wrong password' 
p2 = 'Call from' + IP%2 + 'rejected because extension not found'

c = re.compile(r'(?:' + p1 + '|' + p2 + ')')

你为什么不检查哪个正则表达式匹配呢?在

if 'ip1' in match :
    print match['ip1']
if 'ip2' in match :
    print match['ip2']

或者类似于:

^{pr2}$

甚至是

num = 1000   # can easily handle millions of patterns =)
for i in range(num) :
    name = 'ip%d' % i
    if name in match :
        print match[name]

您可以考虑安装优秀的^{}模块,该模块支持许多高级regex功能,包括branch reset groups,旨在准确解决您在本问题中概述的问题。分支重置组用(?|...)表示。在一个分支重置组中,具有相同位置或名称的不同替代模式的所有捕获组共享相同的捕获组以进行输出。在

请注意,在下面的示例中,匹配的捕获组将成为命名的捕获组,因此您不需要迭代多个组来搜索非空组:

import regex

ip_pattern = r'(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
patterns = [
    'Registration from {ip} - Wrong password',
    'Call from {ip} rejected because extension not found'
]
pattern = regex.compile('(?|%s)' % '|'.join(patterns).format(ip=ip_pattern))
for line in sys.stdin:
    match = regex.search(pattern, line)
    if match:
        print(match['ip'])

演示:https://repl.it/@blhsing/RegularEmbellishedBugs

相关问题 更多 >

    热门问题