0

我有一百万个网址的列表。我必须为每个 url 提取 TLD 并为每个 TLD 制作多个文件。例如收集所有带有 .com 的网址作为 tld 并将其转储到 1 个文件中,另一个申请 .edu tld 等等。在每个文件中,我必须按域名的字母顺序对其进行排序,然后按子域等进行排序。 ct 任何人都可以在 perl 中应用这个跳转吗?

我已使用 URI 模块来提取每个网址的 tld 以及域名和主机名。如何使用 com tld 收集所有网址并将它们转储到 1 个文件中?以及如何按 tld 对每个文件进行排序,然后按域然后按子域等?任何指针?

while(my $line = <$fh1>){   

my $url = $line;

 my @components =  split(/\./, $url);
 my $n_comp = ($components[-1] =~ /^edu|com|net|org|gov$/) ? 2 : 3;
 my $domain = lc(join '.', @components[-$n_comp .. -1]);
 $domain =~ s/^\.//;  # Remove leading . if there is one.
 print $fh3 $domain;
        print $fh3 "\n";


  my $host = URI->new($url)->host();

 # Treat relative URLs as absolute URLs with missing http://.
 $url = "http://$url" if $url !~ /^\w+:/;



 $host =~ s/\.\z//;  # D::PS doesn't handle "domain.com.".
 print $fh2 $host;
 print $fh2 "\n";
 $dps->get_root_domain($host)
 or die $dps->error();
 print $fh4 $dps->tld();
 print $fh4 "\n";


 }
4

1 回答 1

0

这应该适合你。

use strict;
use warnings;
use autodie;

open my $input, '<', shift @ARGV;
my %domain;
while( <$input> ){
  chomp;
  #                                   (  protocol   ) (  domain ) (rest)
  my ($protocol,$domain,$remain) = /^ (?:(\w+):\/\/)? ([^\\\/#]+) ( .* ) /x;

  my ($tld,@domain) = reverse split /[.]/, $domain;

  my $cmp = join '.', @domain;
  push @{ $domain{$tld} }, [ $cmp, $remain, $_ ];
}
close $input;

while( my($tld,$list) = each %domain ){
  open my $out, '>', $tld;
  print {$out} "$_\n" for map{
    $_->[-1]
  }sort{
    $a->[0] cmp $b->[0] ||
    $a->[1] cmp $b->[1] ||
    $a->[2] cmp $b->[2]
  } @$list;
  close $out;
}

  1. 首先,我们将输入分解为我们需要的部分。

    /^ (?:(\w+):\/\/)? ([^\\\/#]+) ( .* ) /x;
    
    • 这将匹配一个可选的http://或类似的。

      (?:(\w+):\/\/)?
    • 这匹配除\/和之外的任何内容#,因为这些字符通常位于域之后。

      ([^\\\/#]+)
    • 这当然与剩下的相匹配。

      ( . )
  2. 我们要对从顶级域到最低级域的 URL 进行排序。所以我们拆分域,然后反转它。

    my ($tld,@domain) = reverse split /[.]/, $domain;
    
  3. 为了比较两个 URL,我们需要一个易于比较的字符串。

    my $cmp = join '.', @domain;
    
  4. 存储信息以备后用。

    push @{ $domain{$tld} }, [ $cmp, $remain, $_ ];
    
  5. 打开我们要打印到的文件。

    while( my($tld,$list) = each %domain ){
      open my $out, '>', $tld;
    
  6. 对要进入当前文件的 URL 列表进行排序。

    ...
    sort{
      $a->[0] cmp $b->[0] ||
      $a->[1] cmp $b->[1] ||
      $a->[2] cmp $b->[2]
    } @$list;
    
  7. 将列表映射到实际 URL。

    ...
    map{
      $_->[-1]
    }
    ...
    
  8. 将列表中的每个 URL打印到文件中。

    print {$out} "$_\n" for ...
    
于 2011-12-24T18:01:42.077 回答