Обратные ссылки в регулярных выражениях совпадают, но не фиксируются - PullRequest
4 голосов
/ 07 июля 2019

Эта программа

say "zipi zape" ~~ /(\w)\w» \s+ \w+({$0})/;

возвращает

「pi zape」
 0 => 「p」
 1 => 「」

что я интерпретирую как обратную ссылку на первое совпадение, сопоставляемое с совпадением нулевой ширины? Может быть, потому что он соответствует $ 0, который относится к '' вне регулярного выражения? Как я мог использовать эти обратные ссылки и одновременно захватывать матч? Примечание : это относится к этой проблеме с документацией , которая требует пояснения использования обратных ссылок.

Ответы [ 2 ]

4 голосов
/ 07 июля 2019

Согласно документации :

Если вам нужно сослаться на захват из другого захвата, сначала сохраните его в переменной

Чтобы вы могли использовать:

say "zipi zape" ~~ /(\w){} :my $c = $0; \w » \s+ \w+($c)/;

Выход :

「pi zap」
 0 => 「p」
 1 => 「p」
3 голосов
/ 07 июля 2019

{$0} не является обратной ссылкой.
Это кодовый блок.
В данном случае это кодовый блок, который абсолютно ничего не делает.

Для того, чтобы он на самом делеиспользоваться как часть регулярного выражения, вокруг которого нужно <>.


Фактически, поскольку () обозначает что-то вроде нового замыкания в отношении $/, это будет пустое регулярное выражениеесли оно действительно использовалось для чего-то.
($/ сбрасывается для каждого (), поэтому $0 также сбрасывается.)

say "zipi zape" ~~ /(\w)\w» \s+ \w+(<{$0}>)/;
Cannot resolve caller INTERPOLATE_ASSERTION(Match:D: Nil:U, BOOTInt, BOOTInt, BOOTInt, BOOTInt, PseudoStash:D); none of these signatures match:
    (Match: Associative:D, $, $, $, $, $, *%_)
    (Match: Iterable:D \var, int \im, int \monkey, int \s, $, \context, *%_)
    (Match: Mu:D \var, int \im, int \monkey, $, $, \context, *%_)
  in block <unit> at <unknown file> line 1

Это происходит потому, что этов основном то же самое, что и (<{Nil}>).


Что вы можете сделать, это обновить $/ перед вторым () с помощью {} и использовать двойные кавычки вокруг $0

say "zipi zape" ~~ /(\w){}\w» \s+ \w+("$0")/;
「pi zap」
 0 => 「p」
 1 => 「p」

Слишком мне это кажется немного ненадежным.
(Это полагается на то, что я считаю ошибкой, если не явной ошибкой.)


Здесь мыполучите ответ Хокон Хагланда о сохранении его в лексической переменной.
(После обновления $/ с помощью {}.)

say "zipi zape" ~~ /(\w){} :my $c = $0; \w » \s+ \w+($c)/;

Lexical переменные не ограничены (), так что это совершенно безопасно сделать.

Я бы лично записал $0, поскольку это единственная часть объекта соответствия внутри $0,используется.

say "zipi zape" ~~ /(\w){} :my $c = ~$0; \w » \s+ \w+($c)/;

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

say "zipi zape" ~~ /(\w)\w» \s+ \w+$0/;

Я также не вижу смысла в добавлении », поскольку \s+ уже заставляет его быть концом слова.

say "zipi zape" ~~ /(\w)\w \s+ \w+$0/;
...