Регулярное выражение не соответствует тому, что я ожидал - PullRequest
1 голос
/ 26 марта 2020

Используя этот код:

    #!usr/bin/perl
    use strict;
    use warnings;

    my $regExp = "xx\n" .
        "xxfirstonegrabxx\n" .
        "xxx\n" .
        "xxfirstonegrabxx\n" .
        "xxsecondtwotakexx\n" .
        "xxxx";

    if ($regExp =~ /first(.*)?grab.*second(.*)?take/s) {
        print "$1\n";
        print "$2\n";
    }

Я ожидал бы вывод:

    one
    two

Но я получаю:

    onegrabxx
    xxx
    xxfirstone
    two

Если я удаляю второе учетная запись "xxfirstonegrabxx \ n". из $ regExp, я получаю-

    one
    two

Как настроить регулярное выражение для поиска сверху вниз и для захвата только первого вхождения шаблона?

Использование Ubuntu 18.04 LTS.

1 Ответ

2 голосов
/ 26 марта 2020

Ты рядом. .* по умолчанию жадный и будет соответствовать столько, сколько может. Если вы измените его с помощью ?, он станет нежадным и будет соответствовать как можно меньшему количеству: .*?. Похоже, что вы пытаетесь сделать это с помощью (.*)?, но поскольку ? находится за пределами паренсов, ? интерпретируется как «необязательный». (.*)? означает «при желании захватить 0 или более объектов с жадностью». (.*?) означает «захватывать 0 или более объектов без жадности».

#!usr/bin/perl
use strict;
use warnings;
use v5.10;

my $regExp = "xx\n" .
    "xxfirstonegrabxx\n" .
    "xxx\n" .
    "xxfirstonegrabxx\n" .
    "xxsecondtwotakexx\n" .
    "xxxx";

if ($regExp =~ /first(.*?)grab.*second(.*?)take/s) {
    say $1;
    say $2;
}

Основное правило - модификаторы, подобные + и ? go внутри захвата. Редко когда вы хотите изменить группу захвата.

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