Perl Regex-从maillog中提取ipv4

Mog*_*rDK 3 regex perl ipv4

我正在perl / mysql / iptables中研究像系统这样的分布式fail2ban。

从/ var / log / messages中提取ipv4地址是可行的,但是现在我想在汤中添加/ var / log / maillog。

我有一个perl正则表达式:[1]

/ (?:25[012345]|2[0-4]\d|1?\d\d?)\.
  (?:25[012345]|2[0-4]\d|1?\d\d?)\.
  (?:25[012345]|2[0-4]\d|1?\d\d?)\.
  (?:25[012345]|2[0-4]\d|1?\d\d?) /x
Run Code Online (Sandbox Code Playgroud)

和来自maillog的一行:

v817YjcU016645: 194.102.60.190.host.ifxnetworks.com [190.60.102.194] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
Run Code Online (Sandbox Code Playgroud)

这里的正则表达式匹配194.102.60.190.host.ifxnetworks.com和[ 190.60.102.194]

在我的代码中($ IP是上面的正则表达式):

if ($line =~ m/($IP)/)
{
    my ($ip) = $1;
Run Code Online (Sandbox Code Playgroud)

在这里找到第一个匹配的类似ip的字符串194.102.60.190.host.ifxnetworks.com

因此,我如何让正则表达式忽略以a结尾的ipv4 .


[1]为了提高可读性Perl支持/ x选项

zdi*_*dim 5

如果这是唯一的问题,请尝试使用负前瞻

my ($ip) = $line =~ /($IP)(?![.\d])/;
Run Code Online (Sandbox Code Playgroud)

适用于显示的数据。

[.\d]需要使用前瞻字符类,因为$IP正则表达式中的最后一项通过允许使用可变数量的数字\d?。因此,(?!\.)单独使用引擎,可以匹配的位数要少一个,然后剩下的位数可以满足非.限制条件。

因此,我们需要同时禁止.模式后面的和。


完整的程序

use warnings;
use strict;

my $t = 'a 194.102.60.190.host.ifxnetworks.com [190.60.102.194] b';

my $n = qr/(?:25[012345]|2[0-4]\d|1?\d\d?)/;

my $IP = qr/$n\.$n\.$n\.$n/;

my @m = $t =~ /($IP)(?![.\d])/g;

print "@m\n";
Run Code Online (Sandbox Code Playgroud)

版画 190.60.102.194


考虑子串90.host。其模式/\d\d?(?!\.)/如下。

首场\d比赛9。但接下来的一个,\d?是可选的(非贪婪),它不匹配,如果图案中的其余然后匹配。确实,(?!\.)看到以下内容0不是.,因此我们匹配90满足(?!\.)。整个模式(错误地)匹配

perl -wE'$_ = q(90.host); @m = /(\d)(\d?)(?!\.)(.)/; say for @m'
Run Code Online (Sandbox Code Playgroud)

版画

9

0

中间的捕获组什么也没捕获,下一个字符(.)0

现在考虑/\d\d?(?![.\d])/相同子字符串的模式。的(?![.\d])要求,后面的内容既不是. 也不是一个数字。因此,必须将可选\d?字符匹配到下一个数字0。由于下一个字符 a,.因此模式失败。

(?![.\d])在上述的一行测试代替(?!\.)没有打印,作为图案不匹配的。(在某些shell中,您可能必须转义!,所以(?\![.\d]),或使用脚本。)

发动机可能不会完全按照所描述的那样运转,这只是对其操作的宽松描述。