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


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.