Курс языка программирования Raku / Регулярные выражения и грамматики / Регулярные выражения / Захваты
Незахватывающие группы
Круглые скобки ( ) делают сразу две работы: они
группируют часть шаблона и захватывают её в
$0, $1 и так далее. Иногда нужна только первая
работа — рассматривать несколько атомов как единое целое, — не расходуя
на это номер захвата. Для этого служат квадратные скобки
[ ], которые группируют без захвата.
Группировка становится важна, как только вы приписываете квантификатор. Квантификатор связывается только с тем атомом, который стоит прямо перед ним, поэтому шаблон ниже повторяет лишь последнюю букву:
say 'abccc' ~~ / abc ** 3 /; # 「abccc」Трижды повторилась только c. Заключите весь кусочек в
[ ], чтобы повторялся он целиком:
say 'abcabcabc' ~~ / [ abc ] ** 3 /; # 「abcabcabc」Теперь [ abc ] — это одна единица, и ** 3
относится к группе.
Поскольку [ ] не занимает ячейку захвата, номера
остаются закреплёнными за теми частями, которые вам действительно нужны.
Сравните с обычным сопоставлением «ключ — значение»:
if 'foo=42' ~~ / (\w+) '=' (\d+) / {
say $0; # 「foo」
say $1; # 「42」
}Пусть ключу может предшествовать слово, которое надо пропустить.
Сгруппируйте этот префикс через [ ], чтобы он не сбивал
нумерацию:
if 'the foo=42' ~~ / [ \w+ \s ]? (\w+) '=' (\d+) / {
say $0; # 「foo」
say $1; # 「42」
}Необязательная группа [ \w+ \s ]? сопоставилась с
the, но не заняла захват, поэтому $0
по-прежнему ключ, а $1 — значение. Если бы вы записали этот
префикс через ( ), всё сдвинулось бы: префикс стал бы
$0, ключ — $1, а значение —
$2.
Правило короткое: используйте ( ), когда совпавший текст
нужно сохранить, и [ ], когда нужна только группировка. Оба
вида принимают квантификаторы и альтернативы — вот почему в приведённой
ранее альтернативе [ cat | dog ] house были квадратные
скобки: там требовалась группировка, а лишний захват — нет.
Навигация по курсу
← Тест — Захваты | Разберите имя файла →
💪 Или перейдите сразу к упражнениям этого
раздела.