JavaScript regex для проверки, замены и извлечения

JavaScript regex сопоставляет текст с шаблонами для валидации, извлечения и замены. Когда входные данные имеют предсказуемый формат — даты, ID, коды — регулярное выражение проверяет строку или извлекает нужные части. Группы захвата в круглых скобках выделяют подстроки, поэтому один шаблон возвращает структурированные данные без ручного разбиения строки.

Пример JavaScript Regex для извлечения по шаблону

Вывод:

Результат появится здесь...

Вывод:

Есть дата: true
Извлечено: 2024/03/15
Заменено: Заказ #A-123 отправлен 2024/03/15

Как работает этот пример

  1. /(\d{4})-(\d{2})-(\d{2})/ задает regex-литерал, который сопоставляет дату в формате ISO. \d{4} соответствует ровно четырем цифрам; круглые скобки создают группы захвата для года, месяца и дня.
  2. datePattern.test(text) возвращает true, если шаблон найден где-либо в строке, но не возвращает детали совпадения.
  3. text.match(datePattern) возвращает массив: полное совпадение по индексу 0, затем каждую группу захвата. Если совпадения нет, метод возвращает null, поэтому перед деструктуризацией при разборе пользовательского ввода нужна проверка.
  4. text.replace(datePattern, "$1/$2/$3") заменяет найденную подстроку. $1, $2 и $3 подставляют группы захвата (год, месяц, день).

Что такое регулярное выражение в JavaScript?

Регулярное выражение в JavaScript — это объект RegExp, который используют для сопоставления комбинаций символов в строках. Регулярные выражения JavaScript создают через литерал (/pattern/flags) или конструктор RegExp (new RegExp("pattern", "flags")). Движок проходит строку слева направо и возвращает первое совпадение, если не включен глобальный флаг (g).

Частые ошибки при использовании JavaScript Regex

Использование глобального regex с test или exec.

const re = /\d+/g;
console.log(re.test("abc 123")); // true
console.log(re.test("abc 123")); // false (lastIndex сдвинулся)
re.lastIndex = 0;
console.log(re.test("abc 123")); // true

С флагами g или y методы test/exec становятся stateful из-за lastIndex. Сбрасывайте его или не используйте g для булевых проверок.

Забыть двойное экранирование в new RegExp().

new RegExp("\d+");  // шаблон это "d+"
new RegExp("\\d+"); // одна или более цифр

В строковом литерале \\ дает один обратный слеш, поэтому regex-движок получает \d, а не d.

Regex-литерал vs конструктор RegExp

Regex-литерал (/pattern/)new RegExp(pattern)
Разбирается при загрузке; синтаксические ошибки видны раньшеКомпилируется во время выполнения; ошибки выбрасываются при достижении кода
Не нужно экранировать как строкуТребуется двойной обратный слеш (\\d)
Шаблон фиксирован в исходном кодеШаблон можно строить из переменных

Используйте литерал для статических шаблонов. Используйте конструктор, когда шаблон включает динамические значения, но сначала экранируйте пользовательский ввод, чтобы избежать regex injection и случайных метасимволов.

const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const re = new RegExp(escapeRegExp("a+b?"), "i");

Больше примеров

Заменить все вхождения через replaceAll:

const masked = "карта 4111-1111-1111-1111".replaceAll(/\d{4}/g, "****");
console.log(masked); // "карта ****-****-****-****"

replaceAll требует флаг g, если аргумент поиска это regex; без g метод выбрасывает TypeError.

Извлечь все совпадения через matchAll:

const tags = [...("#js #regex #es2022".matchAll(/#(\w+)/g))];
console.log(tags.map(m => m[1])); // ["js", "regex", "es2022"]

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

FAQ

Как проверить regex в JavaScript?

Вызовите regex.test(string), чтобы получить булев результат, или string.match(regex), чтобы получить детали совпадения. Для нескольких совпадений используйте string.matchAll(regex) с флагом g, который возвращает итератор всех массивов совпадений вместе с группами захвата.

Поддерживает ли JavaScript lookbehind-утверждения?

Да. Положительный lookbehind (?<=...) и отрицательный lookbehind (?<!...) работают в большинстве современных JavaScript-движков, но в старых браузерах и некоторых встраиваемых рантаймах может возникать синтаксическая ошибка.

Когда использовать new RegExp(), а не литерал?

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