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

Регулярные выражения (RegExp) — шаблоны для поиска, проверки и замены подстрок в тексте, встроенные в JavaScript через объект RegExp и методы строк.

Зачем нужно

RegExp незаменимы для валидации пользовательского ввода (email, телефон, пароль), парсинга форматированного текста, поиска и замены по сложным шаблонам. Без регулярных выражений такие задачи требовали бы десятков строк кода вместо одной строки. Современные именованные группы захвата делают RegExp более читаемыми и удобными для извлечения данных.

Где используется

  • Валидация форм: email, телефон, URL, пароль, почтовый индекс
  • Парсинг логов, CSV, markdown, шаблонов
  • Поиск и замена в текстовых редакторах и обработке строк
  • Роутинг URL в SPA и серверных фреймворках (Express, Vue Router)
  • Токенизация в компиляторах и DSL-парсерах

Основной контент

Синтаксис и флаги

// Два способа создания
const re1 = /hello/gi;        // литерал (предпочтительно)
const re2 = new RegExp('hello', 'gi'); // конструктор (для динамических шаблонов)

// Флаги:
// g — глобальный поиск (все вхождения)
// i — нечувствительность к регистру
// m — многострочный режим (^ и $ — начало/конец строки)
// s — dotAll (. включает \n)
// u — Unicode-режим
// d — индексы совпадений (ES2022)

Основные методы

const text = 'JavaScript и TypeScript — отличные языки';

// test — возвращает boolean
console.log(/typescript/i.test(text)); // true

// match — массив совпадений (без g — первое + группы)
const match = 'Цена: 1500 руб'.match(/\d+/);
console.log(match[0]); // '1500'

// matchAll — итератор всех совпадений (требует флаг g)
const prices = '1500, 2300, 800';
for (const m of prices.matchAll(/\d+/g)) {
  console.log(m[0]); // '1500', '2300', '800'
}

// replace / replaceAll
console.log('foo bar foo'.replace(/foo/g, 'baz')); // 'baz bar baz'
console.log('  hello  '.replace(/^\s+|\s+$/g, '')); // 'hello' (trim)

// split
console.log('a1b2c3'.split(/\d/)); // ['a', 'b', 'c', '']

Классы символов и квантификаторы

// Классы символов
// \d  — цифра [0-9]
// \w  — буква/цифра/_ [a-zA-Z0-9_]
// \s  — пробельный символ
// .   — любой символ кроме \n
// [abc] — один из символов
// [^abc] — любой кроме этих

// Квантификаторы
// *   — 0 или более
// +   — 1 или более
// ?   — 0 или 1
// {n} — ровно n раз
// {n,m} — от n до m раз

const emailRe = /^[\w.+-]+@[\w-]+\.[a-z]{2,}$/i;
console.log(emailRe.test('user@example.com')); // true
console.log(emailRe.test('invalid@'));          // false

const phoneRe = /^\+7[\s-]?\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{2}[\s-]?\d{2}$/;
console.log(phoneRe.test('+7 (999) 123-45-67')); // true

Группы захвата и именованные группы

// Группа захвата 
const dateStr = '2026-04-10';
const dateMatch = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
if (dateMatch) {
  const [, year, month, day] = dateMatch;
  console.log(year, month, day); // '2026' '04' '10'
}

// Именованные группы (?<name>...)
const namedMatch = dateStr.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
const { year, month, day } = namedMatch.groups;
console.log(year, month, day); // '2026' '04' '10'

// Замена с использованием группы
const swapped = '2026-04-10'.replace(
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
  '$<day>.$<month>.$<year>'
);
console.log(swapped); // '10.04.2026'

// Lookahead и lookbehind (позиционные)
console.log('100px 200em'.match(/\d+(?=px)/g));  // ['100'] (перед px)
console.log('$100 €200'.match(/(?<=\$)\d+/g));   // ['100'] (после $)

Частые ошибки

  • Забыть флаг g для matchAll или глобальной замены: без него replace заменит только первое вхождение, matchAll выбросит TypeError.
  • Stateful RegExp с флагом g: объект RegExp с g хранит lastIndex. Повторный вызов test или exec на одном объекте продолжает с прошлого места — создавайте новый объект при каждом использовании или сбрасывайте re.lastIndex = 0.
  • Экранирование в конструкторе: в строке обратный слэш нужно удваивать — new RegExp('\\d+'), а не new RegExp('\d+').
  • Жадные квантификаторы: /<.+>/ захватит всё от первого < до последнего >. Используйте /<.+?>/ (ленивый) или /<[^>]+>/.

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

Ресурсы


🎓 Источник: Регулярные выражения и парсинг в JavaScript

  • 📅 2018-11-29 · YouTube
  • Тезисы: regex — это конечный автомат. Понимание автомата объясняет почему backtracking может быть катастрофическим (ReDoS). Когда regex не подходит — пишите парсер (lexer + grammar)

⚡ Источник: Обновлённые регулярные выражения в JavaScript · AsForJS

  • 📅 2023-06-09 · YouTube
  • Тезисы: новые флаги ES2018+: s (dotAll), d (indices), named groups (?<name>...), lookbehind (?<=...), Unicode property escapes \p{Letter}

⚡ Источник: ⎡RegExp 01⎦ Regular 5 Minutes. Введение · AsForJS

  • 📅 2023-06-14 · YouTube
  • Тезисы: базовые понятия: pattern, flags (g/i/m/s/u/y/d). Литерал /.../ vs new RegExp(...). match vs matchAll vs exec

⚡ Источник: ⎡RegExp 02⎦ Фундаментальная база · AsForJS

  • 📅 2023-06-14 · YouTube
  • Тезисы: якоря (^, $, \b), литералы vs метасимволы. В JS RegExp есть только посимвольное сравнение по умолчанию

⚡ Источник: ⎡RegExp 03⎦ Как в RegExp организованы циклы · AsForJS

  • 📅 2023-06-14 · YouTube
  • Тезисы: квантификаторы *, +, ?, {n,m} — это циклы NFA. Жадный vs ленивый — направление поиска. Возможный exponential backtracking

⚡ Источник: ⎡RegExp 04⎦ Различение в RegExp · AsForJS

  • 📅 2023-06-14 · YouTube
  • Тезисы: альтернация a|b, группы захвата (...), незахватывающие (?:...), lookahead/lookbehind

⚡ Источник: ⎡RegExp 04⎦ Базовые символьные классы · AsForJS

  • 📅 2023-06-16 · YouTube
  • Тезисы: \d, \w, \s и их инверсии. С флагом u \d это только ASCII цифры, для Unicode-цифр нужен \p{Nd}

⚡ Источник: Обзор на JS видео Подсвечиваем НЕ ЛАТИНСКИЕ СИМВОЛы · AsForJS

  • 📅 2023-06-10 · YouTube
  • Тезисы: регулярка /[^\x00-\x7F]/g найдёт все не-ASCII символы. Полезно для проверки кода/контента на смешанный алфавит