RegExp cheatsheet
Создание
const re1 = /pattern/afgls
const re2 = new RegExp("pattern", "flags") // когда паттерн динамический
Флаги
| Флаг | Значение |
|---|
g | global — все совпадения, не только первое |
i | ignore case |
m | multiline — ^/$ работают по строкам, а не по всей строке |
s | dotAll — . матчит и \n тоже |
u | unicode-режим (важно для эмодзи, суррогатных пар) |
y | sticky — матч строго с позиции lastIndex |
Классы символов
| Паттерн | Значение |
|---|
. | любой символ кроме \n (если нет флага s) |
\d / \D | цифра / не цифра |
\w / \W | [A-Za-z0-9_] / наоборот |
\s / \S | пробельный / непробельный |
[abc] | один из перечисленных |
[^abc] | любой, кроме перечисленных |
[a-z], [0-9], [A-Za-z] | диапазон |
Квантификаторы
| Паттерн | Значение |
|---|
* | 0 или больше |
+ | 1 или больше |
? | 0 или 1 |
{n} | ровно n |
{n,} | n или больше |
{n,m} | от n до m |
*?, +?, ??, {n,m}? | lazy-версии (минимально возможное совпадение) |
Greedy vs Lazy:
"<a><b>".match(/<.+>/) // ['<a><b>'] — greedy, всё целиком
"<a><b>".match(/<.+?>/) // ['<a>'] — lazy, минимально
Якоря и границы
| Паттерн | Значение |
|---|
^ | начало строки (или начало после \n с флагом m) |
$ | конец строки |
\b | граница слова |
\B | НЕ граница слова |
Группы
| Паттерн | Значение |
|---|
(...) | захватывающая группа |
(?:...) | незахватывающая (не попадает в результат) |
(?<name>...) | именованная группа |
\1, \2 | обратная ссылка на группу 1, 2 (внутри паттерна) |
(?=...) | lookahead — “за чем следует” |
(?!...) | negative lookahead |
(?<=...) | lookbehind — “перед чем стоит” |
(?<!...) | negative lookbehind |
// lookahead пример: число с разделителями тысяч
"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, ",") // "1,234,567"
Альтернация
/cat|dog/ // "cat" или "dog"
/colou?r/ // "color" или "colour"
Экранирование спецсимволов
Нужно экранировать: . * + ? ^ $ { } ( ) | [ ] \
const escaped = str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
Основные методы строк/RegExp
| Метод | Возвращает | Когда использовать |
|---|
str.match(re) | массив совпадений или null | без g — первое + группы; с g — все совпадения без групп |
str.matchAll(re) | итератор (нужен флаг g) | все совпадения + группы для каждого |
str.replace(re, str|fn) | новая строка | замена (с g — все вхождения) |
str.replaceAll(re, ...) | новая строка | требует флаг g у regex |
str.split(re) | массив строк | разбиение по паттерну |
str.search(re) | индекс или -1 | позиция первого совпадения |
re.test(str) | boolean | просто проверка наличия |
re.exec(str) | массив или null | пошаговый перебор (с g двигает lastIndex) |
replace с callback и группами
"backgroundColor".replace(/[A-Z]/g, (m) => "-" + m.toLowerCase())
// "background-color"
"2024-06-20".replace(/(\d+)-(\d+)-(\d+)/, "$3.$2.$1")
// "20.06.2024"
// именованные группы в replace
"2024-06-20".replace(/(?<y>\d+)-(?<m>\d+)-(?<d>\d+)/, "$<d>.$<m>.$<y>")
Частые шаблоны-заготовки
const EMAIL = /^[\w.+-]+@[\w-]+\.[a-z]{2,}$/i
const URL_SIMPLE = /^https?:\/\/[\w.-]+\.[a-z]{2,}(\/\S*)?$/i
const INTEGER = /^[+-]?\d+$/
const FLOAT = /^[+-]?\d+(\.\d+)?$/
const HEX_COLOR = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i
const WHITESPACE_TRIM = /^\s+|\s+$/g
const MULTI_SPACE = /\s+/g
const WORD_BOUNDARY_SPLIT = /\b/
Частые ловушки
match() без g возвращает группы, с g — нет. Если нужны и все совпадения, и группы — используй matchAll().
exec() в цикле с флагом g использует lastIndex — забыл сбросить или не использовал g → бесконечный цикл или вечный один и тот же результат.
. не матчит перенос строки без флага s.
^/$ без флага m относятся ко всей строке, а не к каждой линии.
- Жадные квантификаторы (
*, +) могут “захватить” больше, чем ожидаешь — проверяй на lazy (*?, +?).
- Regex не умеет считать вложенность (скобки, теги) — для этого нужен парсер/стек (см. LeetCode 394, 10).
← LeetCode
Задачи по сложности
leetcode