Группы захвата

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

Группа захвата позволяет:

  • выделять фрагменты введённого значения;
  • переиспользовать части совпадения;
  • создавать зависимые шаблоны;
  • реализовывать условные конструкции;
  • управлять повторяющимися сегментами;
  • упрощать сложные регулярные выражения.

В контексте Inputmask группы захвата чаще всего используются внутри regex, definitions, validator, а также в сложных масках с динамической логикой.


Синтаксис групп захвата

Базовая группа захвата создаётся круглыми скобками:

(abc)

Пример:

const regex = /(12)(34)/;

Здесь создаются две группы:

  • первая содержит 12;
  • вторая содержит 34.

В обычном JavaScript доступ к ним выполняется через массив совпадений:

const result = "1234".match(/(12)(34)/);

console.log(result[1]); // 12
console.log(result[2]); // 34

Использование групп в Inputmask через regex

Inputmask поддерживает полноценные регулярные выражения.

Пример маски:

Inputmask({
    regex: "(\\d{2})-(\\d{2})"
}).mask("#date");

Допустимые значения:

12-34
56-78

Группы здесь:

(\\d{2})

и

(\\d{2})

Каждая из них захватывает отдельный сегмент.


Экранирование символов

Поскольку строка передаётся в JavaScript, обратные слэши приходится экранировать:

"(\\d{2})"

Без двойного экранирования выражение станет некорректным.

Неверно:

"(\d{2})"

Верно:

"(\\d{2})"

Вложенные группы

Группы могут быть вложенными.

Пример:

Inputmask({
    regex: "((\\d{2})-(\\d{2}))"
}).mask("#nested");

Структура:

Группа 1:
    12-34

Группа 2:
    12

Группа 3:
    34

Вложенные конструкции полезны при:

  • составных форматах;
  • условных проверках;
  • повторяющихся сегментах;
  • сложной валидации.

Группировка без захвата

Иногда требуется только логическое объединение частей выражения без сохранения результата.

Используется синтаксис:

(?:...)

Пример:

Inputmask({
    regex: "(?:\\d{2})-(\\d{2})"
}).mask("#nogroup");

Здесь:

  • первая часть не сохраняется;
  • вторая группа захватывается.

Такой подход уменьшает количество групп и упрощает индексацию.


Нумерация групп

Группы нумеруются слева направо.

Пример:

(AA)(BB)(CC)

Нумерация:

Группа Значение
1 AA
2 BB
3 CC

Вложенные группы тоже участвуют в общей нумерации.

Пример:

((AA)(BB))

Результат:

Группа Значение
1 AABB
2 AA
3 BB

Повторное использование групп

Одно из главных преимуществ групп захвата — обратные ссылки.

Синтаксис:

\1
\2

Пример одинаковых блоков:

Inputmask({
    regex: "(\\d{2})-\\1"
}).mask("#repeat");

Допустимо:

12-12
55-55

Недопустимо:

12-34

Здесь:

\\1

ссылается на первую группу.


Проверка повторяющихся чисел

Пример контроля одинаковых сегментов:

Inputmask({
    regex: "(\\d{3}) \\1"
}).mask("#double");

Допустимо:

123 123
555 555

Недопустимо:

123 456

Проверка парных символов

Группы позволяют проверять симметрию.

Пример:

Inputmask({
    regex: "([A-Z]{2})-\\1"
}).mask("#letters");

Допустимые значения:

AB-AB
ZZ-ZZ

Использование групп в сложных шаблонах

Пример телефонного номера:

Inputmask({
    regex: "(\\+7|8)\\s?\\((\\d{3})\\)\\s?(\\d{3})-(\\d{2})-(\\d{2})"
}).mask("#phone");

Группы:

Группа Значение
1 код страны
2 код города
3 первая часть
4 вторая часть
5 третья часть

Такая структура позволяет:

  • валидировать отдельные сегменты;
  • извлекать части номера;
  • использовать дополнительные проверки.

Группы и альтернативы

Группы особенно полезны при использовании оператора |.

Пример:

Inputmask({
    regex: "(cat|dog|bird)"
}).mask("#animals");

Группа содержит одно из значений:

  • cat
  • dog
  • bird

Комбинация альтернатив и повторов

Пример:

Inputmask({
    regex: "((abc)|(123)){2}"
}).mask("#combo");

Допустимые значения:

abcabc
123123
abc123
123abc

Именованные группы

Современные регулярные выражения JavaScript поддерживают именованные группы.

Синтаксис:

(?<name>...)

Пример:

const regex = /(?<day>\d{2})-(?<month>\d{2})/;

Inputmask частично поддерживает такие конструкции в зависимости от используой версии браузера и движка регулярных выражений.

Пример:

Inputmask({
    regex: "(?<year>\\d{4})"
}).mask("#year");

Группы внутри validator

Пользовательские валидаторы часто используют группы захвата.

Пример:

Inputmask.extendDefinitions({
    "X": {
        validator: function(chrs) {
            return /(\\d{2})/.test(chrs);
        }
    }
});

Более сложный пример:

Inputmask.extendDefinitions({
    "P": {
        validator: function(chrs) {
            const match = chrs.match(/(\\d)(\\d)/);

            if (!match) {
                return false;
            }

            return match[1] !== match[2];
        }
    }
});

Здесь:

  • выполняется захват двух цифр;
  • затем сравниваются группы.

Использование match()

При создании сложной логики Inputmask часто применяется match().

Пример:

validator: function(value) {
    const result = value.match(/(\\d{2})\\/(\\d{2})/);

    if (!result) {
        return false;
    }

    const day = result[1];
    const month = result[2];

    return Number(day) <= 31 &&
           Number(month) <= 12;
}

Группы позволяют получать отдельные части даты.


Использование exec()

Метод exec() тоже активно применяется при работе с Inputmask.

Пример:

const regex = /(\\d{4})-(\\d{2})-(\\d{2})/;

const result = regex.exec("2025-10-15");

Результат:

Индекс Значение
0 полное совпадение
1 2025
2 10
3 15

Группы и динамические маски

Пример динамической проверки:

Inputmask({
    regex: "(\\d{2}|[A-Z]{2})"
}).mask("#dynamic");

Допустимо:

12
AB

Недопустимо:

A1

Группы с квантификаторами

Квантификаторы могут применяться ко всей группе.

Пример:

Inputmask({
    regex: "(abc){3}"
}).mask("#repeatgroup");

Допустимо:

abcabcabc

Необязательные группы

Пример:

Inputmask({
    regex: "(\\+7)?\\d{10}"
}).mask("#optional");

Допустимо:

+71234567890
1234567890

Группа:

(\\+7)?

является необязательной.


Группы и жадность

Регулярные выражения по умолчанию работают жадно.

Пример:

Inputmask({
    regex: "(.*)-(.*)"
}).mask("#greedy");

Первая группа пытается захватить максимум символов.

Для ограничения используется ленивый режим:

Inputmask({
    regex: "(.*?)-(.*?)"
}).mask("#lazy");

Группы в сложной валидации даты

Пример:

Inputmask({
    regex: "(0[1-9]|[12][0-9]|3[01])\\.(0[1-9]|1[0-2])\\.(\\d{4})"
}).mask("#birth");

Группы:

Группа Значение
1 день
2 месяц
3 год

Проверка IP-адреса

Пример:

Inputmask({
    regex: "((25[0-5]|2[0-4]\\d|1\\d\\d|\\d\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d\\d|\\d\\d|\\d)"
}).mask("#ip");

Здесь используются:

  • вложенные группы;
  • повторяющиеся группы;
  • альтернативы;
  • квантификаторы.

Группы в почтовых адресах

Пример:

Inputmask({
    regex: "([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+)\\.([a-zA-Z]{2,})"
}).mask("#email");

Группы:

Группа Значение
1 имя пользователя
2 домен
3 зона

Производительность групп захвата

Большое количество групп:

  • увеличивает нагрузку;
  • усложняет обработку;
  • может замедлять валидацию.

Пример неэффективного выражения:

((a)((b))((c)))

Если захват не нужен, лучше использовать:

(?:a)(?:b)(?:c)

Типичные ошибки

Отсутствие экранирования

Неверно:

"(\d+)"

Верно:

"(\\d+)"

Ошибочная нумерация

Неверно:

((ab)(cd))

Предположение:

\1 = ab

На самом деле:

Ссылка Значение
\1 abcd
\2 ab
\3 cd

Лишние группы

Неверно:

((?:\\d{2}))

Если внешний захват не нужен, конструкцию следует упростить.


Чрезмерная вложенность

Сложные структуры трудно поддерживать:

((((a|b))(c|d)))

Лучше разбивать выражения на отдельные логические части.


Практический пример комплексной маски

Inputmask({
    regex:
        "(\\+7|8)\\s?" +
        "\\((\\d{3})\\)\\s?" +
        "(\\d{3})-(\\d{2})-(\\d{2})"
}).mask("#complex");

Разбор:

Группа Назначение
1 префикс
2 код региона
3 основной блок
4 предпоследний блок
5 последний блок

Такая структура позволяет:

  • анализировать номер по частям;
  • сохранять сегменты отдельно;
  • выполнять дополнительные проверки;
  • интегрировать номер с серверной валидацией.