Отключить захват в уже скомпилированном регулярном выражении?(например, Perl 5.22+, модификатор / n) - PullRequest
0 голосов
/ 16 сентября 2018

Среда: Perl 5.26.2 x64 на Cygwin x64.

Вопрос: после my $re = qr/...(capturing group).../, есть ли способ использовать $re без захватав его группы захвата?

X: Я сопоставляю строки, которые могут быть:

#define FOO(X,Y) SomeComplicatedStuff

или

#define FOO(X,Y) BAR(X,Y)

У меня естьскомпилированное регулярное выражение $re, которое соответствует FOO(X,Y) и включает пронумерованные группы захвата, чтобы разбить совпадение на FOO и X,Y.Я хотел бы сопоставить строки второй формы без необходимости определять отдельное регулярное выражение, например, используя m/$re.+$re/.Это прекрасно работает, но я получаю все группы захвата FOO, когда все, что мне действительно нужно, это группы BAR.

Y: Я думал, что смогу сделать это в5.22+ с модификатором /n, но я не могу заставить его работать.MCVE:

$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/$re$re/; say $1, " ", $2;'
foo bar     # as expected

$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/(?n:$re)$re/; say $1, " ", $2;'
            # I think this should turn off      ^^^  capturing of `foo`
foo bar     # oops - I was hoping for `bar`

$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/(?n:(foo|bar))$re/; say $1, " ", $2;'
bar         # This works, but I had to inline $re within (?n:...).

Примечание: Я также пытался \K:

$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/$re\K$re/; say $1, " ", $2, " ", $&;'
foo bar bar      # was hoping for `bar  bar`

Редактировать Забыл упомянуть - я смотрел на этот связанный вопрос , но это не то же самое постановка проблемы.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Строковое значение $re равно (?^u:(foo|bar)). Другими словами, он устанавливает флаги на те, которые использовались при компиляции шаблона, и, таким образом, отключает /n.

Вы можете использовать любое из следующего:

my $re = qq/(foo|bar)/;    # Note: Gotta escape `\` that are part of regex escapes.
/(?n:$re)$re/

(пример побегов: qr{(fo\w|ba\w)} становится qq{(fo\\w|ba\\w)} при использовании этой техники.)

my $re = qr/foo|bar/;
/$re($re)/

& # x20;

my $re = qr/
   (?<foo_or_bar>) ((?<foo_or_bar>))
   (?(DEFINE)
      (?<foo_or_bar>foo|bar)
   )
/x;
/$re/
0 голосов
/ 16 сентября 2018

Ну, я нашел обходной путь, но это, конечно, не ответ! В любом случае я публикую это здесь, на случай, если это кому-нибудь еще поможет. В моем конкретном случае использования совпадение делится на две части. Таким образом, использование /g в первом совпадении и \G во втором совпадении делает свое дело. Пример:

$ perl -E '
    my $re=qr/(foo|bar)/;
    my $str = "foo bar";

    $str =~ m/$re/g;         # Match `foo`, and set `pos` (because of /g)
    say "Expecting foo: ", $1;

    $str =~ m/\G.+$re/g;     # \G => skip past `foo`, and check ` bar` against `.+$re`
    say "Hoping for bar: ";
'
Expecting foo: foo
Hoping for bar: bar          # Hooray!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...