Яка різниця між $ / і $ ¢ в регулярному вираженні?


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>, але він не зможе отримати доступ до інших foos.


1
Ох! Я інтерпретував документ "Основна відмінність між сферою $/та сферою дії: останній має лише значення всередині регулярного вираження", тобто означає, що це просто вестигіальний слід, як і Cursorє. Коли я прочитав вашу відповідь, я подумав, що це $*TOPя створив у Можливому вдосконаленні? розділ моєї відповіді на ВО "Чому / як потрібна додаткова змінна для узгодження повторного довільного символу з групами захоплення?". Але мої спроби замінити $*TOPна не вдалися. Ви розумієте мою думку в цій відповіді? Чи можете ви змусити це працювати?
raiph

Raiph: Отже, в граматиках оновляється для кожного маркера, тому вам доведеться сказати $*TOP := $¢в TOPлексемі, але це, $*TOPзвичайно, не позбавиться від необхідності вару. Я погоджуюся, було б приголомшливо посилатися на матчі на найвищому рівні. Проблема, зрештою, все ще залишається тією, яку ви ідентифікуєте: коли позиційні / хеш-матчі публікуються на об'єкт відповідності. При використанні - що є токеном - результати будуть визначатися за повідомленням, як тільки { }буде зустрічатися його блок, що додається.
користувач0721090601

Що мені цікаво, це те, що Binex, розвиваючись , я не виявив, що обчислювально гірше розміщувати результати матчів відразу після їх зустрічі. Зрештою, ви натискаєте / вискакуєте або до кешованого списку / хешу, або ви натискаєте / вискакуєте до списку / хешу відповідності. Однак, можливо, є якась внутрішня швидкість, про яку я не знаю, що використовується для LTM, який, ймовірно, є в основі її ( { }припиняє маркер для цілей LTM, і тому швидше запускається / перевіряється, ніж решта маркера в |групуванні)
user0721090601

А-а-а. Я прийшов до висновку був динамічним, і був здивований, коли це не спрацювало. Але тепер копійка зникла, що це лексика, як я міг здогадатися, враховуючи ваше вживання слова "зовнішній", і, як ви пояснюєте, встановлений на початку кожного правила.
raiph

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