Perl正则表达式 - 从maillog中提取ipv4
我正在使用perl/mysql/iptables中的分布式fail2ban类似系统。Perl正则表达式 - 从maillog中提取ipv4
从/ var/log/messages中提取ipv4地址正在工作,但现在我想将/ var/log/maillog添加到汤中。
我有一个perl正则表达式:[1]
/ (?:25[]|2[0-4]\d|1?\d\d?)\.
(?:25[]|2[0-4]\d|1?\d\d?)\.
(?:25[]|2[0-4]\d|1?\d\d?)\.
(?:25[]|2[0-4]\d|1?\d\d?) /x
而且从maillog中的线:
v817YjcU016645: 194.102.60.190.host.ifxnetworks.com [190.60.102.194] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
这里正则表达式同时匹配194.102.60.190
.host.ifxnetworks.com 和[ 190.60.102.194
]
在我的代码中我有($ IP就是上面的正则表达式):
if ($line =~ m/($IP)/)
{
my ($ip) = $1;
这里第一个匹配的IP般串中发现194.102.60.190
.host.ifxnetworks.com
那么,如何获取正则表达式忽略在.
结束一个IPv4
[1]为了可读性的Perl支持/x option
my ($ip) = $line =~ /($IP)(?![.\d])/;
其作品为显示的数据是唯一的问题尝试。
由于$IP
正则表达式中的最后一项允许通过\d?
允许可变数量的数字,所以需要在前瞻中的字符类别[.\d]
。因此单独使用(?!\.)
时,引擎可以匹配少于1位的数字,然后剩下的数字可以满足限制条件的非.
。 ∗
因此,我们需要禁止.
和数字,遵循该模式。
一个完整的程序
use warnings;
use strict;
my $t = 'a 194.102.60.190.host.ifxnetworks.com [190.60.102.194] b';
my $n = qr/(?:25[]|2[0-4]\d|1?\d\d?)/;
my $IP = qr/$n\.$n\.$n\.$n/;
my @m = $t =~ /($IP)(?![.\d])/g;
print "@m\n";
打印190.60.102.194
∗考虑子字符串90.host
。它的模式/\d\d?(?!\.)/
工作如下。
第一\d
比赛9
。但接下来的一个,\d?
,是可选的(非贪婪),它不匹配如果模式的其余部分就可以比拟的。事实上,(?!\.)
看到以下0
是不是.
,所以我们一致9
和0
满足(?!\.)
。整个模式(错误地)匹配
perl -wE'$_ = q(90.host); @m = /(\d)(\d?)(?!\.)(.)/; say for @m'
打印
9 0
中间捕获组打着什么和下一个字符(.)
是0
。
现在考虑同样的子模式/\d\d?(?![.\d])/
。该(?![.\d])
要求,后面的内容既不是.
也不一个数字。因此可选\d?
被迫匹配下一个数字0
。由于下一个字符,然后是一个.
模式失败。
随着(?![.\d])
在单行而不是(?!\.)
没有打印,因为模式根本不匹配。(在一些炮弹,你可能要逃跑!
,所以(?\![.\d])
,或使用脚本。)
所描述的发动机很可能不会去正是,这更是其操作的一个松散的描述。
通常,正则表达式匹配WA在现有的字符序列中创建模式,如果存在不需要的东西,那么不匹配总是比较困难。
可以匹配的IP地址[1]被随后的非点([^.]
):
(?:\d{1,3}\.){3}\d{1,3}[^.]
和在该行的末尾($
)IP地址:
(?:\d{1,3}\.){3}\d{1,3}$
您可以通过在未捕获组((?:
... )
)中更改两个图案(|
):
(?:\d{1,3}\.){3}\d{1,3}(?:[^.]|$)
类似的问题可能是你下一个任务可以排除面前有一个点的IP地址,另外一个问题是,它也将在1.2.3.4.5
匹配2.3.4.5
,从而导致回我的介绍性发言...
我认为您尝试匹配的IP地址最好能找到一些能够检查周围字符的东西。具体说明一下。在开发阶段,尝试通过将匹配到“垃圾模式”来检查不匹配的行。在问题(其中,空格和括号内是可接受的环境)中所示的情况下,我建议使用
(?:[ \[]|^)((?:\d{1,3}\.){3}\d{1,3})(?:[ \]]|$)
[1]我在这里使用的简化的正则表达式,即也匹配333.333.333.333
或000.000.000.000
,当然可以改进以将匹配限制为有效的IP地址,但是对此的解决方案是abundant。
我认为解决方案是分两步进行提取。首先:'my($ line1)= $ line =〜/(\ [)($ IP)(\])/;'匹配'[190.60.102.194]'。其次:'我的($ ip)= $ line =〜/($ IP)/;'与我的意见中的'190.60.102.194' –
@MogensTrasherDK两个阶段不是必要的,请参阅我的最新增加内容。实际匹配('((?:\ d {1,3} \。){3} \ d {1,3})')已包含在最后一个(“建议”)正则表达式中。 – Wolf
@ MogensTrasherDK提醒一下:如果您(可能很快)在某些日志文件中遇到IP地址与其文本上下文之间的其他令人不安的交互作用,请回过头来看看您是否能够正确指定这些模式。 – Wolf
您是否尝试过负向预测?就像'/...(?!\.)/' – zdim
我认为IP地址之后的点只是问题的起点 – Wolf
@zdim是的。匹配'194.102.60.19'0.host.ifxnetworks.com –