В чем разница между $ / и $ ¢ в регулярных выражениях? - PullRequest
12 голосов
/ 27 апреля 2020

Как видно из названия, в чем разница между $/ и ? Кажется, они всегда имеют одно и то же значение:

my $text = "Hello world";

$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;

Оба результата приводят к объектам Match с одинаковыми значениями. Что такое логика c в использовании одного над другим?

1 Ответ

12 голосов
/ 27 апреля 2020

Переменная $/ относится к самому последнему совпадению, а переменная относится к самому последнему внешнему совпадению. В большинстве базовых c регулярных выражений, подобных приведенным выше, это может быть одно и то же. Но, как видно из результатов метода .raku, Match объекты могут содержать другие Match объекты (это то, что вы получаете, когда используете $<foo> или $1 для захвата).

Предположим, вместо этого у нас было следующее регулярное выражение с количественным определением захвата

/ ab (cd { say $¢.from, " ", $¢.to } ) + /

И он запустил бы, чтобы увидеть следующий результат, если мы сопоставим с "abcdcdcd":

0 2
0 4
0 6

Но если мы изменим от использования до $/ мы получаем другой результат:

2 2
4 4
6 6

(причина, по которой .to кажется немного не в том, что она - и .pos - не обновляются до конца блока захвата.)

Другими словами, будет всегда относится к тому, что будет вашим последним объектом сопоставления (то есть, $final = $text ~~ $regex), чтобы вы могли пройти сложное дерево захвата внутри регулярного выражения точно так же, как и после завершения полного соответствия. Итак, в приведенном выше примере вы можете просто сделать $¢[0], чтобы сослаться на первое совпадение, $¢[1] второе, et c.

Внутри блока кода регулярного выражения, $/ будет относиться к mo Первый немедленный матч. В приведенном выше случае это совпадение внутри ( ), и он не будет знать ни о других совпадениях, ни о первоначальном начале сопоставления: только начало блока ( ). Итак, дайте более сложное регулярное выражение:

/ a $<foo>=(b $<bar>=(c)+ )+ d /

Мы можем получить доступ в любой точке, используя $ ¢ всех foo токенов, сказав $¢<foo>. Мы можем получить доступ к bar токенам данного foo, используя $¢<foo>[0]<bar>. Если мы вставим кодовый блок в перехват foo, он сможет получить доступ к bar токенам, используя $<bar> или $/<bar>, но не сможет получить доступ к другим foo s.

...