我编写了以下代码来读取文件,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";
}
答案 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::net的Regexp::Common部分也可能包含您想要的正则表达式。