В чем разница между $ / и $ ¢ в регулярных выражениях?


11

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

my $text = "Hello world";

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

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

Ответы:


11

Переменная $/относится к самому последнему совпадению, а переменная относится к самому последнему внешнему совпадению. В большинстве основных регулярных выражений, подобных приведенным выше, это может быть одно и то же. Но как видно из выходных данных .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]

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

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

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


1
Оооо! Я интерпретировал документ «Основное различие между $/и является областью действия: последний имеет значение только в регулярном выражении», чтобы означать, что это просто рудиментарный след, как Cursorесть. Когда я прочитал ваш ответ, я подумал, будет ли $*TOPя создан в A возможное улучшение? раздел моего ответа SO. «Почему / как нужна дополнительная переменная для сопоставления повторяющегося произвольного символа с группами захвата?». Но мои попытки заменить $*TOPна провалились. Вы понимаете мою точку зрения в этом ответе? Вы можете заставить это работать?
raiph

Райф: То есть в грамматиках обновляется для каждого токена, так что вы должны были бы сказать это $*TOP := $¢в TOPтокене, но это, $*TOPконечно, не избавляет от необходимости в var. Я согласен, что было бы здорово иметь возможность ссылаться на матчи на высшем уровне. Проблема, в конечном счете, все еще остается той, которую вы идентифицируете: когда позиционный / хэш сопоставляет сообщение с объектом соответствия. При использовании - то есть для каждого токена - результаты будут по определению отправляться, как только { }будет обнаружен включающий их блок.
user0721090601

Что меня интересует, так это то, что в процессе разработки Binexя не считаю, что в вычислительном отношении хуже размещать результаты матчей сразу же после их появления. В конце дня вы нажимаете / извлекаетесь из кэшированного списка / хэша, или вы нажимаете / извлекаете из списка / хэша матча. Тем не менее, может быть какая-то внутренняя скорость, которую я не знаю, используемая для LTM, которая, вероятно, является его ядром ( { }терминирует токен для целей LTM, и поэтому с большей вероятностью будет запущена / протестирована, чем остаток токена в |группировке)
user0721090601

Ааа. Я подскочил к выводу, был динамичным, и был удивлен, когда это не сработало Но пенни теперь упало, что оно лексическое, как я мог догадаться, учитывая ваше использование слова «внешний», и, как вы объясняете, устанавливается в начале каждого правила.
raiph

Таким образом, iiuc, в начале правила, создается новый объект соответствия, который записывает позицию курсора соответствующего механизма в исходной входной строке, но в остальном он пуст. (Верно?) Тогда и $/привязываются к одному и тому же объекту, а именно к этому новому объекту сопоставления, который будет записывать, что это правило сопоставляет и фиксирует по мере его развития. Затем, в процессе сопоставления, остается привязанным к этому общему объекту сопоставления, тогда как $/происходит отскок каждый раз, когда создается новый объект сопоставления, поэтому он всегда соответствует, как вы говорите, последнему объекту сопоставления. Правильно?
raiph
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.