Learning Book

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

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

Регулярные выражения (regex) — паттерны для поиска и замены в строках. Мощный, но требующий осторожности инструмент.

Создание

// Литерал (предпочтительно — компилируется один раз)
const pattern = /hello/i;

// Конструктор (когда паттерн строится динамически)
const word = 'hello';
const dynamic = new RegExp(word, 'i');

Флаги

/pattern/i   // i — регистронезависимый поиск
/pattern/g   // g — все вхождения (не только первое)
/pattern/m   // m — многострочный режим (^ и $ совпадают с началом/концом строки)
/pattern/s   // s — точка совпадает с \n (dotAll)
/pattern/gi  // можно комбинировать

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

// Символьные классы
/\d/  // цифра [0-9]
/\w/  // слово [a-zA-Z0-9_]
/\s/  // пробельный символ (\t, \n, пробел)
/\D/  // НЕ цифра
/\W/  // НЕ словесный символ
/\S/  // НЕ пробел

// Квантификаторы
/a*/  // 0 или больше
/a+/  // 1 или больше
/a?/  // 0 или 1
/a{3}/   // ровно 3
/a{2,4}/ // от 2 до 4

// Позиции
/^hello/  // начало строки
/world$/  // конец строки
/\bhello\b/ // граница слова

// Группы
/(abc)/   // захватывающая группа
/(?:abc)/ // незахватывающая группа

Методы строк с regex

const str = 'Hello World 123';

// test — проверить наличие
/\d+/.test(str);     // true

// match — найти совпадения
str.match(/\w+/);    // ['Hello'] — первое совпадение (без флага g)
str.match(/\w+/g);   // ['Hello', 'World', '123'] — все (с флагом g)

// matchAll — итератор всех совпадений (с группами)
const matches = [...str.matchAll(/(\w+)/g)];
// каждый элемент — массив: [полное совпадение, группа1, ...]

// replace — замена
str.replace(/\d+/, 'NUM');   // 'Hello World NUM'
str.replace(/[aeiou]/gi, '*'); // замена всех гласных

// search — позиция первого совпадения
str.search(/\d+/); // 12

// split — разбивка по регулярному выражению
'one1two2three'.split(/\d/); // ['one', 'two', 'three']

Захватывающие группы

const date = '2024-01-15';
const match = date.match(/(\d{4})-(\d{2})-(\d{2})/);
// match[0] = '2024-01-15' — полное совпадение
// match[1] = '2024'       — группа 1
// match[2] = '01'         — группа 2
// match[3] = '15'         — группа 3

// Именованные группы
const named = date.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
named.groups.year;  // '2024'
named.groups.month; // '01'

// Замена с группами
'2024-01-15'.replace(
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
  '$<day>.$<month>.$<year>'
); // '15.01.2024'
Не используйте флаг g с методом test() в цикле — regex с g запоминает позицию (lastIndex), что приводит к неожиданным результатам. Создавайте новый экземпляр внутри цикла или не используйте g.

По умолчанию квантификаторы жадные — захватывают как можно больше:

'&lt;b&gt;bold&lt;/b&gt; and &lt;i&gt;italic&lt;/i&gt;'.match(/<.+>/);
// '&lt;b&gt;bold&lt;/b&gt; and &lt;i&gt;italic&lt;/i&gt;' — захватил всё от первого < до последнего >

// Ленивый квантификатор с ? — захватывает как можно меньше
'&lt;b&gt;bold&lt;/b&gt; and &lt;i&gt;italic&lt;/i&gt;'.match(/<.+?>/);
// '&lt;b&gt;' — только первый тег