6

Perl の新機能。

次のようなレポートを解析する必要があります。

2012-05-29@emaillocalpart@emaildomain@customerid@errormessage@messageid

私が使用した:

my @fields = split(/@/, $line, 6);

ほとんどの場合は問題なく動作しますが、エラー メッセージに電子メール アドレスと、その電子メールの @ 記号の後のすべてのテキストが含まれ、文字列の最後がメッセージ ID で終わることがあります。

@s の量をチェックして条件付き解析を行うことを考えましたが、より良い方法はありますか?

編集:

目的の出力は文字列のリストであり、エラー メッセージには含まれているものはすべて含まれています (場合によっては電子メール アドレスも含まれます)。

同じレポートを使用する他のアプリケーションがあるため、セパレーターを変更したり、出力をエスケープしたりすることはできません。

レポートのサンプル行:

2012-05-29@joedoe@example.com@AB99-5@440 4.4.1 Some error occurred@XYZ35
2012-05-29@foobar@invalid.com@ZZ88-6@550 5.1.1 <foobar@invalid.com>... User Unknow@GGH93
2012-05-29@barfoo@invalid.com@YY88-0@550 5.1.1 barfoo@invalid.com no such user@GGH93

行 1 を解析した後の @fields の予期される内容:

2012-05-29
joedoe
example.com
AB99-5
440 4.4.1 Some error occurred
XYZ35

そして2行目を解析した後:

2012-05-29
foobar
invalid.com
ZZ88-6
550 5.1.1 <foobar@invalid.com>... User Unknow
GGH93
4

4 に答える 4

4

たとえば、$teststr に次のものが含まれている場合: '2012-05-29@emaillocalpart@emaildomain@customerid@error@me@ssage@messageid';

次のコード:

my @fields2=split('@',$teststr);
my @finalfields=@fields2[0 .. 3];
my $finalat=$#fields2-1;
my $errormessage=join('@',@fields2[4 .. $finalat]);
push(@finalfields,$errormessage);
push(@finalfields,$fields2[$#fields2]);

print Data::Dumper->Dump([@finalfields])."\n";

次の出力が得られます。

$VAR1 = '2012-05-29';
$VAR2 = 'emaillocalpart';
$VAR3 = 'emaildomain';
$VAR4 = 'customerid';
$VAR5 = 'error@me@ssage';
$VAR6 = 'messageid';

お詫び - それはかなり冗長な解決策です。1 つの正規表現で同じことを行うこともできます。

$teststr=~/(.[^@]*)@(.[^@]*)@(.[^@]*)@(.[^@]*)@(.*)@(.[^@]*)/;
print "$1\n$2\n$3\n$4\n$5\n$6\n";
于 2012-06-05T13:21:35.737 に答える
1

daximの答えに似ていますが、別の書き方です。

my $re = '^' . '([^@]*)@'x4 . '(.*)@([^@]*)$';
my @fields = $line =~ /$re/; 

ここでエラーチェックを行うこともできます。

my @fields = $line =~ /$re/ or die "can't parse '$line'";
于 2012-06-05T14:08:47.763 に答える
1

これは、オプションの電子メール アドレスを適切に解析します。

$str = '5-29@foobar@invalid.com@ZZ88-6@550 5.1.1 <foobar@invalid.com>... User Unknow@GGH93';
#$str= '2012-05-29@joedoe@example.com@AB99-5@440 4.4.1 Some error occurred@XYZ35';

$str =~ s/(\<[^\>]+\>)/!!/; # replace an email address with !!
$email = $1; # store the email

@fields = split(/@/,$str); # split on @

s/!!/$email/ foreach (@fields); # find the old !! and replace with the email address

print STDERR map { "$_ \n" } @fields; # print fields to standard error

ここで動作することを確認してください。これは、オプションの電子メールが 1 つしかないことを前提としています。ちょっとした作業で、任意の数の< >区切られた電子メールを含む文字列に対して機能するように変更できます。

于 2012-06-05T14:02:04.597 に答える
0

これを処理する最も簡単な方法は、次@のような非常に一般的ではない別の区切り文字に変更することです。;;;;

于 2012-06-05T13:21:22.633 に答える