1

私はこのサイトや他のサイトを精査して、必要なことを行うための最良の方法を見つけましたが、役に立ちませんでした. 基本的に、いくつかの名前と電子メール アドレスを含むテキスト ファイルがあります。それぞれの名前と電子メール アドレスは、それぞれの行にあります。電子メール アドレスを取得して、別のテキスト ファイルに出力する必要があります。これまでのところ、印刷できたのは「メールアドレスが見つかりません」というメッセージだけです。何かご意見は?ありがとう!!

#!/usr/bin/perl

open(IN, "<contacts.txt") || die("file not found");
#chooses the file to read
open(OUT, ">emailaddresses.txt");
#prints file
$none = "No emails found!";
$line = <IN>;

for ($line)
{
    if ($line =~ /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/g)
    {
        print (OUT $line);
    }
    else
    {
        print (OUT $none);
    }
}

close(IN);
close(OUT);
4

1 に答える 1

8

まず、常に use strict; use warnings. これは、正しいスクリプトを作成するのに役立ち、デバッグ時に非常に役立ちます。

また、three-arg-open を使用します。

open my $fh, "<", $filename or die qq(Can't open "$filename": $!);

失敗の理由( )も含めました$!が、これも良い習慣です。

(開いているファイルハンドルで) ファイルを読み取るイディオムは次のとおりです。

while (<$fh>) {
  chomp;
  # The line is in $_;
}

また

while (defined(my $line = <$fh>)) { chomp $line; ... }

あなたがしたことは、1 行を に読み込み$line、ループ内のその1 つの項目をループすることforでした。

(Perl にはcontextの概念があります。演算子 likeは、コンテキスト<$fh>に応じて異なる動作をします。一般に、スカラー変数 ( $sigil) を使用するとスカラー コンテキストが強制@され、配列の sigil はリスト コンテキストを引き起こします。これは PHP とはまったく異なります。)

私はあなたのコードを次のように書き直します:

use strict; use warnings;
use feature 'say';
my $regex = qr/[A-Z0-9._%+-]+\@[A-Z0-9.-]+\.[A-Z]{2,4}/i; # emails are case insensitive
my $found = 0;

while (<>) { # use special ARGV filehandle, which usually is STDIN
  while (/($regex)/g) {
    $found++;
    say $1;
  }
}
die "No emails found\n" unless $found;

のように呼び出されperl script.pl <contacts.txt >emailaddresses.txtます。シェルはあなたの友人であり、パイプでやり取りできるプログラムを作成するのは良い設計です。

アップデート

ファイル名をハードコーディングしたい場合は、上記のスクリプトを、私が示した 3 つの引数の open と組み合わせます。

use strict; use warnings; use feature 'say';
use autodie; # does `... or die "Can't open $file: $!"` for me
my $regex = qr/[A-Z0-9._%+-]+\@[A-Z0-9.-]+\.[A-Z]{2,4}/i;
my $found = 0;

my $contact_file = "contacts.txt";
my $email_file   = "emailaddresses.txt";

open my $contact, "<", $contact_file;
open my $email, ">", $email_file;

while (<$contact>) {    # read from the $contact filehandle
  while (/($regex)/g) { # the /g is optional if there is max one address per line
    $found++;
    say {$email} $1;    # print to the $email file handle. {curlies} are optional.
  }
}
die "No emails found\n" unless $found; # error message goes to STDERR, not to the file
于 2013-03-29T20:00:03.383 に答える