Регулярные выражения

Регулярные выражения в JavaScript представляют собой механизм работы с текстовыми данными, позволяющий описывать шаблоны строк и выполнять поиск, проверку, извлечение и замену фрагментов текста с высокой гибкостью. Этот инструмент встроен в язык и реализован через объект RegExp, а также набор методов строк.


Регулярное выражение — это формальный шаблон, описывающий множество строк. В JavaScript оно может быть создано двумя способами:

const re1 = /abc/;
const re2 = new RegExp("abc");

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

Ключевое отличие заключается в том, что литерал компилируется один раз при парсинге кода, тогда как RegExp может создаваться во время выполнения.


Основные методы работы

Регулярные выражения чаще всего используются через методы строк:

  • match() — поиск совпадений
  • search() — индекс первого совпадения
  • replace() — замена подстрок
  • split() — разбиение строки

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

const text = "hello world";
console.log(text.match(/world/));

Флаги регулярных выражений

Флаги изменяют поведение поиска.

Основные флаги:

  • g — глобальный поиск (все совпадения)
  • i — нечувствительность к регистру
  • m — многострочный режим
  • s — точка (.) включает переносы строк
  • u — работа с Unicode
  • y — «липкий» режим (поиск с текущей позиции)

Пример:

const re = /abc/gi;

Метасимволы и их значение

Регулярные выражения используют специальные символы, задающие поведение шаблона.

Основные метасимволы:

  • . — любой символ, кроме перевода строки
  • ^ — начало строки
  • $ — конец строки
  • * — 0 или более повторений
  • + — 1 или более повторений
  • ? — 0 или 1 повторение
  • {n} — ровно n повторений
  • {n,} — n или больше
  • {n,m} — от n до m повторений

Пример:

const re = /^a.*z$/;

Символьные классы

Символьные классы позволяют задавать набор допустимых символов.

Примеры:

  • [abc] — любой символ a, b или c
  • [a-z] — диапазон букв
  • [0-9] — цифры
  • [^0-9] — любой символ, кроме цифр

Пример проверки числа:

const re = /^[0-9]+$/;

Предопределённые классы

JavaScript предоставляет сокращённые обозначения:

  • \d — цифра
  • \D — не цифра
  • \w — символ слова (буквы, цифры, _)
  • \W — не символ слова
  • \s — пробельный символ
  • \S — не пробел

Пример:

const re = /\d{3}-\d{2}-\d{2}/;

Квантификаторы и жадность

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

По умолчанию они жадные, то есть захватывают максимально возможное совпадение.

const text = "<b>bold</b>";
console.log(text.match(/<.*>/));

Результат: <b>bold</b>

Чтобы сделать поведение «ленивым», используется ?:

console.log(text.match(/<.*?>/));

Результат: <b>


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

Скобки позволяют группировать выражения:

const re = /(ab)+/;

Захваченные группы доступны в результате match:

const result = "ababab".match(/(ab)+/);
console.log(result[0]);
console.log(result[1]);

Ненумеруемые группы (non-capturing)

Если группа нужна только для логики, но не для захвата, используется ?::

const re = /(?:ab)+/;

Это снижает накладные расходы и упрощает результаты.


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

Современный JavaScript поддерживает именование групп:

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

Использование:

const match = "2026-05-21".match(re);
console.log(match.groups.year);

Альтернация

Символ | работает как логическое «или»:

const re = /cat|dog/;

Совпадение будет либо с cat, либо с dog.


Границы слов и строк

Регулярные выражения поддерживают якоря:

  • ^ — начало строки
  • $ — конец строки
  • \b — граница слова
  • \B — не граница слова

Пример поиска слова:

const re = /\bword\b/;

Lookahead и lookbehind

Это нулевые утверждения, проверяющие контекст без включения его в результат.

Позитивный просмотр вперёд:

const re = /foo(?=bar)/;

Негативный просмотр вперёд:

const re = /foo(?!bar)/;

Позитивный просмотр назад:

const re = /(?<=bar)foo/;

Негативный просмотр назад:

const re = /(?<!bar)foo/;

Методы объекта RegExp

Помимо методов строк, существует API самого регулярного выражения:

  • test() — проверка совпадения
  • exec() — извлечение совпадений с подробной информацией

Пример:

const re = /\d+/;
console.log(re.test("123"));

Работа с глобальным флагом

При использовании g поведение exec изменяется: регулярное выражение хранит внутренний индекс lastIndex.

const re = /\d+/g;
const str = "12 34 56";

console.log(re.exec(str));
console.log(re.exec(str));

Каждый вызов продолжает поиск с последней позиции.


Unicode и флаг u

Флаг u обеспечивает корректную работу с многобайтовыми символами:

const re = /\u{1F600}/u;

Без u такие символы могут обрабатываться некорректно.


Практические шаблоны

Проверка email

const re = /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i;

Проверка телефона

const re = /^\+?\d{10,15}$/;

Извлечение чисел из текста

const re = /\d+/g;

Замена строк с использованием групп

const text = "2026-05-21";
const result = text.replace(/(\d{4})-(\d{2})-(\d{2})/, "$3.$2.$1");

Результат: 21.05.2026


Использование функции в replace

replace может принимать функцию:

const text = "1 2 3";

const result = text.replace(/\d/g, (match) => {
  return Number(match) * 2;
});

Ошибки и типичные проблемы

  1. Избыточная жадность квантификаторов
  2. Отсутствие экранирования специальных символов
  3. Неправильное использование g с test()
  4. Игнорирование Unicode при работе с международным текстом
  5. Сложные выражения, ухудшающие читаемость

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

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

const re = /\./;

Если этого не сделать, символ будет интерпретирован как метасимвол.


Производительность регулярных выражений

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

  • чрезмерной вложенности
  • использовании backtracking с катастрофическим ростом
  • больших входных данных

Оптимизация часто сводится к упрощению шаблонов и снижению количества альтернатив.


Сравнение RegExp и строковых методов

Строковые методы быстрее и проще, но ограничены:

  • includes() — простое наличие
  • startsWith() — начало строки
  • endsWith() — конец строки

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


Контекст использования в JavaScript

Регулярные выражения активно применяются в:

  • валидации форм
  • парсинге логов
  • обработке пользовательского ввода
  • трансформации текста
  • поисковых алгоритмах
  • токенизации

Их роль особенно заметна в задачах, где структура текста изменчива и не фиксирована заранее.