0

100 万の Web アドレスのリストがあります。すべての URL の TLD を抽出し、TLD ごとに複数のファイルを作成する必要があります。たとえば、tld として .com を含むすべての Web アドレスを収集し、それを 1 つのファイルにダンプし、別のファイルは .edu tld などに適用します。さらに各ファイル内で、ドメイン名、サブドメインなどのアルファベット順にソートする必要があります。

URI モジュールを使用して、各 Web アドレスの tld とドメインおよびホスト名を抽出しました。com tld ですべての Web アドレスを収集し、それらを 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. 2 つの 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 に答える