Курс языка программирования 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 были квадратные скобки: там требовалась группировка, а лишний захват — нет.

Навигация по курсу

Тест — Захваты   |   Разберите имя файла


💪 Или перейдите сразу к упражнениям этого раздела.