我有一个以下正则表达式,只有当逗号位于(>或@)之后才会使用'\ n'代替逗号(,)(不是下一个字符,而是在发生“>或@之后的任何时候) “。
$address =~ s/([^@>]+[@>][^,]+),\s*/$1\n/g;
以上正则表达式将输入转换为输出,如下所示,
输入:
$address ="mail1, local<mail1@mail.local>, mail2@mail.local, <mail3@mail.local>, mail4 local<mail4@mail.local>"
输出:
mail1, local<mail1@mail.local>
mail2@mail.local
<mail3@mail.local>
mail4, local<mail4@mail.local>
现在我要做的是,为了达到同样的目的,但如果逗号(,)在双引号(“)之间,则避免用'\ n'替换它。
基本上对于以下输入我期望输出如下所示。
输入:
$address = "mail1,local<mail1@mail.local>, \"mail2@,mail.local\"<mail2@mail.local>";
当前输出:
mail1,local<mail1@mail.local>
"mail2@
mail.local" <mail2@mail.local>
预期产出:
mail1,local<mail1@mail.local>
"mail2@,mail.local" <mail2@mail.local>
答案 0 :(得分:3)
请注意,您的规范存在问题,"mail2@,mail.local"<mail2@mail.local>
将被分为"mail2@
和mail.local"<mail2@mail.local>
,因为逗号位于@
之后。这个解决方案做了我认为你的意思
我建议您将字符串解析为标记并单独打印每个标记
此解决方案寻找
<...>
"..."
逗号可能两边都有空格
任何其他字符的字符串
如果令牌包含$seen_email
或@
,则标记>
设置为 true 。如果该标志为true,则任何逗号都将转换为换行符并重置标志,而其他任何内容都将逐字打印
use strict;
use warnings 'all';
my $address = 'mail1,local<mail1@mail.local>, "mail2@,mail.local"<mail2@mail.local>';
{
my $seen_email;
while ( $address =~ / \G ( <[^<>]*> | "[^"]*" | \h*,\h* | [^"<>,]+ ) /xg ) {
my $token = $1;
$seen_email ||= $token =~ /[\@>]/;
if ( $seen_email and $tok =~ /^\h*,/ ) {
$token = "\n";
$seen_email = undef;
}
print $token;
}
}
mail1,local<mail1@mail.local>
"mail2@,mail.local"<mail2@mail.local>
如果您必须进行替换而不是将修改后的字符串打印到STDOUT
,那么将上述解决方案重构为s///eg
将为您做到这一点
use strict;
use warnings 'all';
use feature 'say';
my $address = 'mail1,local<mail1@mail.local>, "mail2@,mail.local"<mail2@mail.local>';
{
my $seen_email;
$address =~ s{ \G ( <[^<>]*> | "[^"]*" | \h*,\h* | [^"<>,]+ ) }{
my $token = $1;
$seen_email ||= $tok =~ /[\@>]/;
if ( $seen_email and $token =~ /^\h*,/ ) {
$token = "\n";
$seen_email = undef;
}
$token;
}exg;
}
say $address;
输出相同