Группы, диапазоны и альтернации

Группы, диапазоны и альтернации

Технический фундамент структурных шаблонов

Когда regex описывает формат, а не слово, ключевыми становятся:

  • группировка частей шаблона ((...));
  • выбор альтернатив (a|b|c);
  • точные диапазоны символов и длины;
  • различие между захватывающей и незахватывающей группой.

Это позволяет проектировать выражение как маленькую "грамматику" формата, а не набор случайных кусков.

Почему эта тема важна

На практике ты редко ищешь один символ. Обычно нужно описать структуру строки: префикс, разделитель, часть с цифрами, один из нескольких допустимых вариантов. Группы, диапазоны и альтернации дают этот уровень выразительности.

Ключевой момент: ты начинаешь описывать не отдельный символ, а логические куски шаблона.

Проверь себя: почему формат user-123 удобнее проверять одной структурой, чем цепочкой из нескольких if?

Группы ( ... )

Круглые скобки объединяют часть шаблона в блок.

const regex = /(cat)/;
console.log(regex.test('my cat')); // true

Группы нужны для:

  • логического объединения;
  • повторений целого блока (тема следующего урока);
  • извлечения частей совпадения.
const dateRegex = /(\d{2})\.(\d{2})\.(\d{4})/;
const result = 'Дата: 15.09.2025'.match(dateRegex);
console.log(result[1]); // 15
console.log(result[2]); // 09
console.log(result[3]); // 2025

Смотри, что важно: группы нумеруются слева направо.

Смотри, что важно: result[0] всегда содержит полное совпадение, а группы начинаются с result[1]. И еще: если совпадения нет, match(...) вернет null, поэтому в прод-коде обычно используют проверку или ?..

Альтернация |

a|b означает: совпадает либо a, либо b.

console.log(/cat|dog/.test('my dog')); // true
console.log(/cat|dog/.test('my bird')); // false

Чтобы альтернация применялась к целому блоку, используй группу.

console.log(/(small|medium|large)/.test('size: medium')); // true

Здесь часто путаются: без скобок ^cat|dog$ работает не так, как ожидают. Для точной логики лучше писать ^(cat|dog)$.

console.log(/^cat|dog$/.test('my dog')); // true (сработала часть dog$)
console.log(/^cat|dog$/.test('catalog')); // true (сработала часть ^cat)

console.log(/^(cat|dog)$/.test('my dog')); // false
console.log(/^(cat|dog)$/.test('dog')); // true

Проверь себя: чем отличаются /cat|dog/ и /^(cat|dog)$/?

Диапазоны в символьных классах

Диапазоны в [ ... ] задают набор допустимых символов.

  • [A-Z] - большая латиница;
  • [a-z] - маленькая;
  • [0-9] - цифры;
  • [A-Za-z0-9] - буквы + цифры.
const usernameRegex = /^[A-Za-z0-9_]+$/;

console.log(usernameRegex.test('dev_42')); // true
console.log(usernameRegex.test('dev-42')); // false

Мини-сценарий: валидация логина без пробелов и спецсимволов.

Негруппирующие скобки (?: ... )

Иногда нужно только объединить часть шаблона, но не сохранять ее как отдельную группу.

const regex = /^(?:GET|POST|PUT)$/;
console.log(regex.test('POST')); // true

Дополнительный пример: шаблон версии API с группами и альтернацией.

const versionRegex = /^v(1|2)\.(\d+)$/;

console.log(versionRegex.test('v1.15')); // true
console.log(versionRegex.test('v3.15')); // false

Это снижает "шум" в результатах захвата, если тебе не нужно читать result[1], result[2] и т.д.

Реальные микро-сценарии

  1. Лог-уровни.

Шаблон ^(INFO|WARN|ERROR)$ проверяет допустимые уровни.

  1. Формат кода заказа.

Например, ^(WEB|APP)-\d{6}$ разрешает только два канала и 6 цифр.

  1. Проверка метода HTTP.

^(GET|POST|DELETE|PATCH)$ фильтрует входные параметры.

Частые ошибки новичков

  • Забывать группировать альтернацию.
  • Ожидать, что диапазон [A-z] означает только буквы (он захватывает лишние символы между Z и a).
  • Путать "группа для структуры" и "группа для извлечения".
  • Делать regex слишком сложным без промежуточной проверки.

Анти-провал: строи шаблон по частям и тестируй каждый кусок отдельно, прежде чем склеивать всё в один regex.

Что будет, если изменить входные данные

Для ^(WEB|APP)-\d{6}$:

  • WEB-123456 пройдет;
  • APP-000001 пройдет;
  • MOBILE-123456 не пройдет (недопустимая альтернатива);
  • WEB-12345 не пройдет (мало цифр).

Проверь себя: что изменится, если убрать ^ и $ в этом шаблоне?

Краткий итог

  • Группы ( ... ) объединяют части regex и помогают извлекать данные.
  • Альтернация | задает "или" между вариантами.
  • Диапазоны [A-Z], [0-9] формируют точные наборы символов.
  • Для чистой структуры без захвата используй (?: ... ).
  • Правильная группировка и тестирование по частям резко снижает ошибки в сложных шаблонах.