Извлечение IP-адреса из полной строки после использования файла slurping и использования регулярных выражений для сопоставления IP-адреса

Я написал следующий код для чтения файла, взлома, определения 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 ответа

Решение

Похоже, вы уже делаете групповое совпадение, просто измените $_ на $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";
}

Получить в привычку использовать use strict; а также use warnings; в КАЖДОМ Perl-скрипте. Это поможет вам поймать проблемы.

Уведомление $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-адрес. Является ли это проблемой, зависит от файлов или данных, к которым вы собираетесь применить регулярное выражение. Чтобы ограничить все 4 номера в IP-адресе 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 может иметь регулярное выражение по вашему желанию.

Другие вопросы по тегам