在啜饮文件并使用正则表达式匹配IP地址后,从整行提取IP地址

时间:2014-06-17 05:05:37

标签: regex perl slurp

我编写了以下代码来读取文件,slurp,识别IP地址并使用哈希结构跟踪每个地址的出现次数。问题是,不是我的密钥是从正则表达式匹配的IP地址,而是密钥是IP地址出现的整行。我该如何解决? (我认为问题与啜饮逐行完成的事实有关)

%ipcount;

@fileslurp = <FH>;
foreach(@fileslurp){
    if($_ =~ m/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/){
        $ipcount{$_}++;
    }
}

$numIP = scalar keys %ipcount;

print "Number of unique IP: $numIP \n"; 

foreach $ipaddress (sort { $ipcount{b} <=> $ipcount{a} } keys %ipcount){
    print "$ipaddress: $ipcount{$ipaddress} \n";
}

2 个答案:

答案 0 :(得分:1)

看起来你已经在进行群组匹配,只需在添加哈希值时将$ _更改为$ 1.

%ipcount;

@fileslurp = <FH>;
foreach(@fileslurp){
    if($_ =~ m/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/){
        $ipcount{$1}++;
    }
}

$numIP = scalar keys %ipcount;

print "Number of unique IP: $numIP \n"; 

foreach $ipaddress (sort keys %ipcount){
    print "$ipaddress: $ipcount{$ipaddress} \n";
}

养成在每个perl脚本中使用use strict;use warnings;的习惯。它会帮助你解决问题。

答案 1 :(得分:0)

注意$ipcount{$_},您在这里使用$_这是您的行,将其更改为$ipcount{$1},其中$1将被捕获的IP地址。


还有一件事是你的匹配IP地址的正则表达不正确。匹配IP地址是正则表达式复杂性和准确性之间权衡的另一个好例子。 \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b会匹配任何IP地址,但也会匹配999.999.999.999,就像它是有效的IP地址一样。这是否是一个问题取决于您打算应用正则表达式的文件或数据。要将IP地址中的所有4个数字限制为0..255,您可以使用以下正则表达式。它将4个IP地址中的每一个存储到捕获组中。您可以使用这些组来进一步处理IP号。自由间距模式允许它适合页面的宽度。

\b(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]?)\b

如果您不需要访问单个数字,可以使用量词缩短正则表达式:

\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

同样,您可以将快速正则表达式缩短为\b(?:\d{1,3}\.){3}\d{1,3}\b

Regexp::Common::netRegexp::Common部分也可能包含您想要的正则表达式。