W3docs

Захватывающие группы

Захватывающие группы в регулярных выражениях JavaScript: нумерованные, именованные (?<name>), незахватывающие (?:) группы, использование с match, matchAll и replace.

Захватывающая группа — это часть регулярного выражения, заключённая в скобки (...). Она выполняет две задачи: группирует часть шаблона так, чтобы квантификаторы и чередование применялись ко всему фрагменту целиком, и запоминает совпавший текст, чтобы его можно было прочитать позже.

Именно это превращает регулярное выражение из простой проверки «да/нет» в инструмент извлечения данных. Вместо того чтобы просто знать, что дата совпала, можно отдельно получить год, месяц и день. На этой странице рассматриваются нумерованные группы, именованные группы, незахватывающие группы, а также поведение групп при работе с match, matchAll и replace.

Понимание захватывающих групп

При нахождении совпадения всё совпадение сохраняется по индексу 0 результирующего array, а каждая захватывающая группа записывается по следующим индексам (1, 2, 3, …) в том порядке, в котором открывающие скобки групп встречаются слева направо.

Синтаксис и базовое использование

Простой пример:

javascript— editable

match[0] — это всегда вся совпавшая строка. match[1] и match[2] содержат текст, захваченный первой и второй парами скобок. Группы нумеруются по их открывающей (, поэтому даже вложенные группы имеют предсказуемый порядок (см. ниже).

Расширенное использование и приёмы

Вложенные захватывающие группы

Группы могут быть вложенными, что позволяет выполнять более сложное сопоставление с образцом. Нумерация следует каждой открывающей скобке слева направо:

javascript— editable

Внешняя группа (группа 1) захватывает foobar, а внутренние группы (2 и 3) захватывают foo и bar по отдельности. Если группа является необязательной и не участвует в совпадении, её слот содержит undefined.

Незахватывающие группы

Иногда нужно сгруппировать части шаблона — чтобы применить квантификатор или чередование — без расхода нумерованного слота. Незахватывающие группы используют синтаксис (?:...):

javascript— editable

Здесь foo сгруппирован, но не захвачен, поэтому bar становится группой 1, а не группой 2. Незахватывающие группы сохраняют результирующий array чистым и работают немного быстрее, когда совпавший текст не нужен.

Распространённый случай применения — повторение фрагмента без захвата каждого повторения:

javascript— editable

Практические примеры

Разбор дат

Захватывающие группы позволяют разбирать и переформатировать даты из строк:

javascript— editable

Этот код извлекает год, месяц и день, затем форматирует дату в другом стиле.

Извлечение информации из URL

Ещё один распространённый вариант использования — извлечение частей URL:

javascript— editable

Это регулярное выражение отдельно захватывает протокол, домен, путь и строку запроса.

Советы по эффективному использованию захватывающих групп

  1. Планируйте свои группы: заранее обдумайте, какие части шаблона нужно захватывать.
  2. Используйте незахватывающие группы при необходимости: применяйте (?:...) для группировки без захвата, чтобы упростить результирующий array.
  3. Именованные захватывающие группы: в современном JavaScript (ES2018+) можно использовать именованные захватывающие группы для улучшения читаемости.
  4. Поведение глобального флага: при использовании флага g вместе с String.prototype.match() возвращается array всех совпавших строк без захватывающих групп. Используйте String.prototype.matchAll() для детального извлечения групп с глобальным флагом.

Именованные захватывающие группы

Нумерованные группы ненадёжны: добавьте группу в середину — и все индексы после неё сдвинутся. Именованные захватывающие группы (ES2018+) решают эту проблему, присваивая каждой группе метку вида (?<name>...). Захваченные значения появляются в object groups вместо (или в дополнение к) нумерованным индексам:

javascript— editable
Информация

Для всего, кроме простейших шаблонов, отдавайте предпочтение именованным захватывающим группам — они делают и само регулярное выражение, и код, который его читает, самодокументируемым.

Использование групп с match, matchAll и replace

Способ чтения захваченных групп зависит от вызываемого метода.

Без флага gmatch возвращает группы

Не-глобальный String.prototype.match() возвращает один array совпадения со всеми группами, точно так же, как в примерах выше. Это наиболее распространённый способ извлечения одной записи.

С флагом g — используйте matchAll для групп

При добавлении глобального флага g метод match() возвращает плоский array только полных строк совпадений — группы теряются. Чтобы получить группы для каждого совпадения, используйте String.prototype.matchAll(), который возвращает итератор array совпадений (каждый со своим object groups):

javascript— editable

Обращение к группам в replace

В строке замены String.prototype.replace() можно ссылаться на захваченные значения по номеру через $1, $2, … или по имени через $<name>:

javascript— editable

Для большего контроля можно передать функцию в replace. Её аргументами будут полное совпадение, затем каждая захваченная группа, а в конце (при использовании имён) — object groups:

javascript— editable

Обратные ссылки

После того как группа захватила текст, можно снова сопоставить тот же текст позже в том же шаблоне с помощью обратной ссылки\\1 для нумерованных групп или \\k<name> для именованных. Это удобно для поиска повторяющихся слов или сопоставления парных кавычек:

javascript— editable

Обратные ссылки — отдельная тема; подробности см. в разделе Обратные ссылки в шаблоне.

Связанные темы

Заключение

Захватывающие группы в регулярных выражениях JavaScript предоставляют мощный инструмент для работы со сложными строковыми шаблонами. Освоив их, вы сможете выполнять сложные текстовые манипуляции, извлекать значимые данные и легко обрабатывать замены. Будь то разбор дат, обработка URL или переформатирование строк — захватывающие группы обеспечивают гибкость и мощь, необходимые для решения задач продвинутой обработки текста. Изучайте приведённые примеры, практикуйтесь на собственных шаблонах и совершенствуйте свои навыки JavaScript для решения любых задач по манипуляциям со строками.

Практика

Практика
Какие из следующих утверждений о захватывающих группах в регулярных выражениях JavaScript верны?
Какие из следующих утверждений о захватывающих группах в регулярных выражениях JavaScript верны?
Was this page helpful?