Как поставить условие ниже RegEx? - PullRequest
0 голосов
/ 08 июня 2018

У меня есть нижеследующее регулярное выражение, которое ставит '\ n' вместо запятой (,), только когда запятая идет после (> или @) (не следующий символ, но в любое время после появления "> или @".

$address =~ s/([^@>]+[@>][^,]+),\s*/$1\n/g;

Выше Regex преобразует ввод в вывод, как показано ниже,

Ввод:

$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 голосов
/ 08 июня 2018

Обратите внимание, что с вашей спецификацией есть проблема в том, что "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;
    }
}

output

mail1,local<mail1@mail.local>
"mail2@,mail.local"<mail2@mail.local>

Update

Ifу вас должна быть замена вместо печати измененной строки в 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;

output

Outputидентично

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...