W3docs

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

Регулярные выражения в JavaScript: создание шаблонов, флаги, ключевые методы string и RegExp, поиск и валидация текста.

Введение в регулярные выражения (Regex) в JavaScript

Регулярные выражения, широко известные как regex, — это последовательности символов, образующие шаблоны поиска. Они являются незаменимыми инструментами программирования для обработки текста: поиска, редактирования и манипулирования строковыми данными. Regex применяется в самых разных областях: валидация данных, парсинг, подсветка синтаксиса и многое другое.

Например, можно быстро проверить, похожа ли строка на адрес электронной почты:

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test("[email protected]")); // true
console.log(emailRegex.test("not-an-email"));    // false

Примечание: это упрощённый шаблон. Для валидации в продакшене рассмотрите более строгие правила или специализированные библиотеки.

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

  • Веб-разработка: валидация полей форм, разбор URL и поиск по содержимому.
  • Анализ данных: извлечение конкретных шаблонов из больших наборов данных.
  • Редактирование текста: поиск и замена текста в документах или кодовых базах.
  • Языки программирования: большинство современных языков, включая JavaScript, поддерживают regex.

Создание регулярного выражения

JavaScript предоставляет два способа создания regex, и разница между ними важна на практике.

// 1. Literal syntax — compiled once when the script loads.
const re1 = /\d+/g;

// 2. Constructor — useful when the pattern is built from a variable.
const word = "cat";
const re2 = new RegExp(word + "s?", "i"); // matches "cat" or "cats", case-insensitive

console.log(re1 instanceof RegExp); // true
console.log(re2.source, re2.flags); // cats? i

Используйте литеральный синтаксис для фиксированных шаблонов — он короче, и движок компилирует его заранее. К конструктору RegExp обращайтесь, когда шаблон формируется динамически (например, из пользовательского ввода). Помните, что в строке обратный слеш нужно удваивать: "\\d" в конструкторе эквивалентно \d в литерале.

Как regex связан со строками: ключевые методы

Шаблон полезен только вместе с методом, который его выполняет. Вот те, которые вы будете использовать каждый день.

const text = "The year 2023 follows 2022.";

// test() → boolean: "does it match anywhere?"
console.log(/\d{4}/.test(text)); // true

// String.match() with /g → array of all matches
console.log(text.match(/\d{4}/g)); // [ '2023', '2022' ]

// String.replace() → returns a new string
console.log(text.replace(/\d{4}/g, "YEAR")); // The year YEAR follows YEAR.

// RegExp.exec() → one match at a time, with capture groups
console.log(/(\d{4})/.exec(text)[1]); // 2023

// String.matchAll() → iterator of full match objects (needs /g)
for (const m of text.matchAll(/(\d{4})/g)) {
  console.log(m[0], "at index", m.index);
}
// 2023 at index 9
// 2022 at index 22

Выбирайте метод в зависимости от задачи: test() — для проверки «да/нет», match()/matchAll() — для извлечения данных, replace() — для преобразования текста. Флаг g (глобальный) превращает «первое совпадение» во «все совпадения», поэтому он необходим для match, matchAll и операций замены всех вхождений.

Чтение шаблона: основные строительные блоки

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

const log = "2023-06-19 ERROR user=42 path=/login";

// \d  digit      \w  word char     \s  whitespace
// .   any char   +   1 or more     [] a set of chars
const match = log.match(/(\d{4}-\d{2}-\d{2})\s+(\w+)\s+user=(\d+)/);

console.log(match[1]); // 2023-06-19  (the date group)
console.log(match[2]); // ERROR       (the level group)
console.log(match[3]); // 42          (the user id group)

Каждый (...) — это захватывающая группа, текст которой попадает в массив результата. \d, \w и \s — это классы символов; квантификаторы + и {4} указывают, сколько раз должен повторяться предшествующий токен. Комбинируя эти элементы, можно извлекать структурированные данные из обычного текста.

Краткий справочник: флаги и квантификаторы

КатегорияСимвол/ФлагОписание
ФлагиiПоиск без учёта регистра
gГлобальный поиск (найти все совпадения)
mМногострочный режим (^ и $ совпадают с границами строк)
sРежим dotAll (. совпадает с переводами строк). Требует поддержки ES2018+.
uРежим Unicode
yРежим sticky (совпадение только начиная с lastIndex)
Квантификаторы*0 или более раз
+1 или более раз
?0 или 1 раз
{n}Ровно n раз
{n,}n или более раз
{n,m}От n до m раз

Распространённые подводные камни

Несколько сюрпризов, которые подстерегают почти всех при изучении regex в JavaScript:

  • Regex с флагом /g запоминает, где остановился. При повторном использовании одного и того же объекта RegExp с test() или exec() значение lastIndex продвигается между вызовами, поэтому второй test() может вернуть false для строки, в которой явно есть совпадение. Используйте новый литерал при каждом вызове или сбрасывайте re.lastIndex = 0.

    const re = /a/g;
    const s = "a";
    console.log(re.test(s)); // true
    console.log(re.test(s)); // false — lastIndex moved past the end
  • Динамические шаблоны требуют экранирования пользовательского ввода. Если вы строите regex из текста, введённого пользователем, символы вроде . или ( будут интерпретироваться как специальные. Предварительно экранируйте их:

    const escape = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    const userInput = "a.b";
    const re = new RegExp(escape(userInput));
    console.log(re.test("axb"));  // false — the dot is now literal
    console.log(re.test("a.b"));  // true
  • По умолчанию квантификаторы жадные. .+ захватывает как можно больше; добавьте ?, чтобы сделать его ленивым (.+?). Подробнее: Жадные и ленивые квантификаторы.

Маршрут обучения

Эта страница является отправной точкой раздела курса о регулярных выражениях. Пройдите следующие главы по порядку для полного практического понимания темы:

  1. Шаблоны и флаги — построение шаблонов и влияние флагов (i, g, m, s, u, y) на поиск.
  2. Классы символов\d, \w, \s и их отрицания.
  3. Unicode: флаг u и класс \p{...} — работа с многоязычным текстом и эмодзи.
  4. Якоря: начало строки ^ и конец $ — совпадение на границах.
  5. Многострочный режим якорей, флаг m — привязка ^ и $ к каждой строке.
  6. Граница слова \b — поиск целых слов.
  7. Экранирование специальных символов — использование ., (, ? как обычных символов.
  8. Наборы и диапазоны [...] — пользовательские наборы символов.
  9. Квантификаторы +, *, ?, {n} — указание количества повторений.
  10. Жадные и ленивые квантификаторы — управление объёмом захвата.
  11. Захватывающие группы — извлечение и именование частей совпадения.
  12. Обратные ссылки \n и \k<name> — повторное использование захваченного текста.
  13. Альтернация (ИЛИ) | — совпадение с одним из нескольких вариантов.
  14. Опережающая и ретроспективная проверка — утверждения нулевой ширины.
  15. Катастрофический откат — диагностика и предотвращение патологической производительности.
  16. Флаг sticky y, поиск с заданной позиции — привязанный поиск на основе позиции.

Описание методов, выполняющих эти шаблоны, см. в главах Объект RegExp и его методы и Строки в JavaScript.

Пройдя все эти уроки, вы сможете создавать эффективные шаблоны regex для поиска, валидации и преобразования текста в JavaScript.

Практика
Какой флаг в regex JavaScript заставляет шаблон находить все совпадения в строке, а не только первое?
Какой флаг в regex JavaScript заставляет шаблон находить все совпадения в строке, а не только первое?
Was this page helpful?