在Perl中有选择地拆分字符串

Cle*_*ves 6 regex perl parsing split

Perl新手.

我需要解析一个如下所示的报告:

2012-05-29@emaillocalpart@emaildomain@customerid@errormessage@messageid
Run Code Online (Sandbox Code Playgroud)

我用了:

my @fields = split(/@/, $line, 6);
Run Code Online (Sandbox Code Playgroud)

大部分时间它工作正常,但有时错误消息将包含一个电子邮件地址和该电子邮件上的@符号后面的所有文本,直到字符串的结尾将以我的消息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
Run Code Online (Sandbox Code Playgroud)

解析第1行后@fields的预期内容:

2012-05-29
joedoe
example.com
AB99-5
440 4.4.1 Some error occurred
XYZ35
Run Code Online (Sandbox Code Playgroud)

解析第2行之后:

2012-05-29
foobar
invalid.com
ZZ88-6
550 5.1.1 <foobar@invalid.com>... User Unknow
GGH93
Run Code Online (Sandbox Code Playgroud)

Qta*_*tax 1

与 daxim 的答案类似,但另一种编写方式:

my $re = '^' . '([^@]*)@'x4 . '(.*)@([^@]*)$';
my @fields = $line =~ /$re/; 
Run Code Online (Sandbox Code Playgroud)

您可能还想在这里进行一些错误检查:

my @fields = $line =~ /$re/ or die "can't parse '$line'";
Run Code Online (Sandbox Code Playgroud)