0

我编写了以下代码来读取文件、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";
}
4

2 回答 2

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;and的习惯。use warnings;它将帮助您发现问题。

于 2014-06-17T05:08:13.347 回答
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,您可以使用以下正则表达式。它将IP地址的4个数字中的每一个存储到一个捕获组中。您可以使用这些组来进一步处理 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的Regexp ::Common::net部分也可能具有您想要的正则表达式。

于 2014-06-17T05:16:43.073 回答