如何将条件放在RegEx下面?

时间:2018-06-08 06:55:00

标签: regex perl

我有一个以下正则表达式,只有当逗号位于(>或@)之后才会使用'\ 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>

1 个答案:

答案 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;

输出

输出相同