Perl - Как подсчитать и распечатать вхождения доменов в массиве адресов электронной почты? - PullRequest
1 голос
/ 11 мая 2011

Я боролся с этим уже пару дней и, похоже, не могу этого понять.

У меня есть массив адресов электронной почты, которые были созданы с помощью push(@emails,$email) в цикле while.

Я пытаюсь создать список уникальных доменов с количеством вхождений каждого в массиве.

Упорядочено по количеству вхождений.

Итак, если массив @emails имеет:

john@yadoo.com ringo@geemail.net george@zoohoo.org paul@yadoo.com

Я могу напечатать:

yadoo.com 2
geemail.net 1
zoohoo.org 1

Я нашел этот пример на основе электронных писем в файле, но, ПУТЬ над моей головой. Может ли кто-нибудь помочь мне в более подробном примере кода, который можно использовать с массивом адресов электронной почты?

perl -e 'while(<>){chomp;/^[^@]+@([^@]+)$/;$h{$1}++;}
foreach $k (sort { $h{$b} <=> $h{$a} } keys %h)  {print $h{$k}." ".$k."\n";} infile

Я также пытался: (больше к моему уровню непонимания)

foreach my $domain (sort keys %$domains) {
  print "$domain"."=";
  print $domains->{$domain}."\n";
};

И

my %countdoms;
$countdoms{$_}++ for @domains;
print "$_ $countdoms{$_}\n" for keys %countdoms;

Лучший результат, который я получил из множества разных попыток, - это общий счет (который был 1812 (точный счет) с числом 2 рядом с ним. Я близко, возможно?

Ответы [ 4 ]

2 голосов
/ 11 мая 2011

Вместо того, чтобы дать вам другой ответ, позвольте мне объяснить вам, что делает ваш пример кода:

while(<>){chomp;/^[^@]+@([^@]+)$/;$h{$1}++;}
foreach $k (sort { $h{$b} <=> $h{$a} } keys %h)  {print $h{$k}." ".$k."\n";} 

Первая строка подсчитывает домены из писем в файлах.

while(<>) перебирает входные файлы построчно. Входные файлы - это файл (ы), переданные в качестве аргументов, или стандартный ввод, если аргументы не переданы. Каждая строка помещается в $_.

chomp; просто удаляет символ новой строки в конце $_.

/^[^@]+@([^@]+)$/ - это регулярное выражение, которое анализирует домен и применяется к $_. Он проверяет что-то, что не имеет «@» в первой части, затем «@», а затем «@» в последней части. Он запоминает последнюю часть, которая будет сохранена в $1. ^ и $ означают начало и конец строки соответственно.

$h{$1}++; использует домен (в $1) для увеличения счетчика в хэше %h. Это работает, даже если его нет, потому что undef ведет себя здесь как 0.

Чтобы сделать эту работу для вашего списка, вы можете просто сделать

foreach(@emails) {/^[^@]+@([^@]+)$/;$h{$1}++;}

Вторая строка печатает домены из хеша %h.

sort { $h{$b} <=> $h{$a} } keys %h возвращает список доменов, отсортированных по убыванию, с помощью функции сравнения $h{$b} <=> $h{$a} для просмотра количества. Обратите внимание, что это b <=> a, а не <=> b, это делает его убывающим.

Остальная часть строки 2 выводит результат.

1 голос
/ 11 мая 2011

Если ваш адрес электронной почты заполнен в массиве, вы получите счетчик для каждого домена. Я уверен, что кто-то может сделать что-то красивее!

my @emails = ('john@yadoo.com','ringo@geemail.net','george@zoohoo.org','paul@yadoo.com');

my %domainCount;

foreach(@emails){
    if ($_ =~ /@(\w+.*)/){
        $domainCount{$1}++;
    }
}

for my $domain (sort { $domainCount{$b} <=> $domainCount{$a}} keys %domainCount ){
    print "$domain - $domainCount{$domain}\n";
}
0 голосов
/ 11 мая 2011

Еще один вариант:

use strict;
use warnings;

my @array 
    = qw<john@yadoo.com ringo@geemail.net george@zoohoo.org paul@yadoo.com>
    ;
my %dom_count;
$dom_count{ $_ }++ foreach map { ( split '@' )[-1] } @array;
foreach my $pair ( 
    sort { $b->[1] <=> $a->[1] or $a->[0] cmp $b->[0] } 
    map  { [ $_ => $dom_count{ $_ } ] } keys %dom_count 
    ) { 
    print "@$pair\n";
}
0 голосов
/ 11 мая 2011

Это немного грубо, потому что я ржав на Perl, но это должно сработать:

use strict;
$|=1;
my ($dom, %hsh);
my @arr = ('john@yadoo.com', 'ringo@geemail.net', 'george@zoohoo.org', 'paul@yadoo.com');
foreach (@arr) {
    ($dom) = ($_ =~ /.*\@(.*)$/);
    $hsh{$dom}++;
}
foreach (keys %hsh) {
    print ("$_:$hsh{$_}\n");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...