regexp в JavaScript: что такое регулярные выражения и как их использовать

Регулярные выражения в JavaScript — это компактный язык шаблонов для поиска, проверки, извлечения и замены фрагментов текста. Если объяснить проще, regexp работает как очень точный фильтр: он не «понимает» смысл текста как человек, зато блестяще распознаёт форму — цифры, даты, пробелы, домены, коды, артикулы, повторяющиеся символы и тысячи других текстовых конструкций, которые в прикладной разработке встречаются ежедневно.

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

Регулярное выражение — это шаблон, по которому движок JavaScript сопоставляет строки и находит в них нужные последовательности символов. На практике это означает, что вместо десятков условий с проверкой каждого символа можно описать правило одной компактной конструкцией.

В JavaScript регулярные выражения создаются двумя основными способами:

  1. Через литерал: удобно, когда шаблон известен заранее.
  2. Через конструктор RegExp: подходит, когда шаблон собирается динамически.
const re1 = /hello/i;
const re2 = new RegExp('hello', 'i');

Здесь флаг i означает нечувствительность к регистру. То есть шаблон найдёт и Hello, и HELLO, и hello.

У регулярных выражений в JavaScript несколько типовых сценариев применения:

  • валидация ввода в формах;
  • поиск данных в логах и сообщениях;
  • очистка строк;
  • разделение текста на фрагменты;
  • замена по шаблону;
  • извлечение данных из URL, email, телефонов, кодов заказов.

Если представить строку как железнодорожную линию, то regexp — это контролёр с очень точным маршрутом. Он знает, где начинается путь, через какие «остановки» должен пройти шаблон, какие символы можно пропустить, а какие обязательны, и где именно проверка заканчивается. Например, у шаблона /^\d{4}-\d{2}-\d{2}$/ маршрут начинается строго в начале строки, затем останавливается на четырёх цифрах, потом на дефисе, потом на двух цифрах, ещё раз на дефисе, затем на двух цифрах и заканчивается строго в конце строки. Никаких лишних остановок, отклонений и «посадок по пути».

Из чего состоят regexp: символы, классы, якоря и квантификаторы

Структура регулярного выражения — это набор специальных токенов, каждый из которых задаёт конкретное правило сопоставления. Понимание этих элементов даёт возможность читать и писать шаблоны без догадок.

Обычные символы

Если символ не имеет специального значения, он ищется буквально.

/cat/

Такой шаблон найдёт последовательность cat в строке my cat sleeps.

Метасимволы

Метасимволы — это служебные обозначения, которые управляют логикой поиска.

Символ Значение Пример
. любой символ, кроме перевода строки /a.c/
\d любая цифра /\d+/
\w буква, цифра или подчёркивание /\w+/
\s пробельный символ /\s/
\D не цифра /\D+/
\W не буква, не цифра и не подчёркивание /\W/
\S не пробельный символ /\S+/

Классы символов

Класс символов — это перечисление допустимых символов в одной позиции. Он особенно полезен, когда вариантов немного и они заранее известны.

/[abc]/   // a или b или c
/[A-Z]/   // любая латинская заглавная буква
/[0-9]/   // любая цифра

Отрицание внутри квадратных скобок задаётся через ^:

/[^0-9]/

Это означает «любой символ, кроме цифры».

Якоря начала и конца строки

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

/^hello/   // строка должна начинаться с hello
/world$/   // строка должна заканчиваться на world
/^cat$/    // строка должна быть ровно cat

Вот здесь особенно полезно думать о маршруте буквально. У шаблона /^AB\d{6}Z$/ точный путь такой:

  1. Начало строки.
  2. Остановка 1: символ A.
  3. Остановка 2: символ B.
  4. Остановки 3–8: ровно шесть цифр.
  5. Остановка 9: символ Z.
  6. Конец строки.

Если хотя бы одна «остановка» пропущена, маршрут считается недействительным.

Квантификаторы

Квантификатор задаёт, сколько раз должен повторяться предыдущий элемент. Это один из самых мощных инструментов regexp.

Квантификатор Значение Пример
* 0 или более раз /ab*/
+ 1 или более раз /ab+/
? 0 или 1 раз /colou?r/
{3} ровно 3 раза /\d{3}/
{2,5} от 2 до 5 раз /\w{2,5}/

Как использовать регулярные выражения в JavaScript на практике

Использование regexp в JavaScript строится вокруг стандартных методов строк и объектов RegExp, которые позволяют проверять наличие совпадения, извлекать данные и заменять текст. Фактически разработчик выбирает не «можно ли сделать regex», а «какой именно метод лучше соответствует задаче».

Метод test()

test() возвращает true или false, если совпадение найдено или не найдено.

/\d/.test('Order 42'); // true

Это лучший выбор для валидации формата.

Метод match()

match() извлекает совпадения из строки.

'Price: 199 USD'.match(/\d+/);

Метод replace()

replace() заменяет найденные фрагменты на новый текст.

'2025/05/26'.replace(/\//g, '-');

Метод search()

search() возвращает индекс первого совпадения или -1.

'user@example.com'.search(/@/);

Метод split()

split() делит строку по шаблону, а не только по фиксированному символу.

'apple, orange;banana'.split(/[;,]\s*/);

Я часто советую начинающим сначала формулировать задачу словами, а уже потом превращать её в regexp. Если сразу писать шаблон, мозг цепляется за символы и легко пропустить логику: где начало, где конец, какие элементы обязательны, а какие допустимы как опция.

Регулярных выражений в JavaScript: базовые шаблоны для реальных задач

Базовые шаблоны — это готовые конструкции для типовых сценариев, которые экономят время и уменьшают число ошибок при работе со строками. Однако каждый такой шаблон нужно проверять на границы применимости, потому что «похоже на рабочее» и «действительно корректно» — не одно и то же.

Проверка целого числа

/^\d+$/

Маршрут проверки:

  1. Начало строки.
  2. Одна или более цифр.
  3. Конец строки.

Подходящие строки: 7, 2025, 0001. Неподходящие: 12a, 45, 4.2.

Проверка даты в формате YYYY-MM-DD

/^\d{4}-\d{2}-\d{2}$/

Этот шаблон проверяет именно форму записи, а не реальность календарной даты. Строка 2025-13-99 по форме подходит, но логически неверна. Поэтому для дат лучше сочетать regexp с дополнительной проверкой через объект Date.

Извлечение всех чисел из текста

const result = 'ID: 52, room 804'.match(/\d+/g);

Флаг g включает глобальный поиск — то есть находит не одно совпадение, а все.

Удаление лишних пробелов

const cleaned = text.replace(/\s+/g, ' ').trim();

Это частый приём при нормализации пользовательского ввода.

Простейшая проверка email

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

Такой шаблон полезен для быстрой интерфейсной проверки, но не покрывает все допустимые адреса по стандартам RFC. По данным Internet Message Format RFC 5322 и более поздних спецификаций, формат email может быть гораздо сложнее, чем принято в бытовых примерах. Поэтому в production-валидации лучше комбинировать regex, подтверждение почты и серверную проверку.

Флаги regexp: как меняется поведение поиска

Флаги — это модификаторы, которые задают режим работы регулярного выражения и напрямую влияют на результат поиска. Один и тот же шаблон без флагов и с флагами может вести себя как два разных инструмента.

Флаг Назначение Пример
g искать все совпадения /\d/g
i игнорировать регистр /hello/i
m многострочный режим для ^ и $ /^item/m
s точка захватывает перевод строки /a.b/s
u корректная работа с Unicode /\p{L}/u
y липкий поиск с текущей позиции /\d/y

Особенно важен флаг u. Без него работа с некоторыми символами Unicode может быть некорректной. Это практически значимо в проектах с многоязычным интерфейсом, эмодзи, именами пользователей и текстами, содержащими расширенные наборы символов.

Группы, альтернативы и захват подстрок

Группы — это способ объединять части шаблона, извлекать фрагменты текста и применять правила повторения к целым блокам. Они делают регулярные выражения не просто фильтром, а инструментом структурного разбора строки.

Обычные группы

/(\d{4})-(\d{2})-(\d{2})/

Здесь отдельно захватываются год, месяц и день.

const m = '2025-05-26'.match(/(\d{4})-(\d{2})-(\d{2})/);
// m[1] = 2025
// m[2] = 05
// m[3] = 26

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

/(?:https?:\/\/)?example\.com/

Конструкция (?:...) группирует выражение без сохранения подмаски в результирующем массиве.

Альтернатива

/cat|dog|bird/

Шаблон найдёт один из перечисленных вариантов.

Именованные группы

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

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

С практической точки зрения люди чаще ошибаются не в синтаксисе групп, а в том, что забывают про жадность шаблона. Психологически это объяснимо: человек склонен читать шаблон слева направо как инструкцию, а движок regexp ещё и применяет внутренние правила выбора совпадения. В итоге кажется, что выражение «должно было взять меньше», но оно берёт больше, потому что квантификатор жадный.

Жадные и ленивые квантификаторы: где чаще всего ошибаются

Жадный квантификатор пытается захватить максимально возможный фрагмент, а ленивый — минимально достаточный для совпадения. Эта разница критична при парсинге HTML-подобных строк, кавычек, скобок и повторяющихся блоков.

/<div>.*<\/div>/

Такой шаблон может захватить слишком много.

/<div>.*?<\/div>/

А здесь *? делает поиск ленивым.

Практическое наблюдение: в формах, шаблонах писем и простом текстовом парсинге именно жадные квантификаторы создают наибольшее число «тихих» ошибок — не падение кода, а неверный результат. Разработчик видит, что match что-то нашёл, и не сразу замечает, что найденный фрагмент длиннее ожидаемого.

Когда я проверяю чужой код с regexp, первым делом смотрю на сочетания .* и .+. В реальных задачах именно они чаще всего превращают аккуратный шаблон в пылесос, который засасывает лишний текст.

Какие ошибки при работе с regexp в JavaScript встречаются чаще всего

Типичные ошибки в regexp — это отсутствие якорей, избыточная жадность, неправильное экранирование и попытка решить регулярным выражением задачу, которая требует полноценного парсера. Проще говоря, regex силён в шаблонах, но не всемогущ.

1. Отсутствие якорей при валидации

/\d+/

Этот шаблон лишь находит цифры внутри строки, но не проверяет, что вся строка состоит только из цифр.

Правильно:

/^\d+$/

2. Неверное экранирование точки

/example.com/

Точка здесь означает любой символ. Поэтому шаблон совпадёт и с exampleXcom.

Правильно:

/example\.com/

3. Попытка одной regex-проверкой гарантировать корректность сложных данных

Например, формат даты, URL или email можно проверить по форме, но не всегда по логике и стандартам. URL регулируется RFC 3986, а email — несколькими RFC, и их полное покрытие одним шаблоном обычно неоправданно сложно.

4. Игнорирование Unicode

Современные интерфейсы давно вышли за пределы ASCII. Если строка содержит комбинированные символы, национальные алфавиты или эмодзи, шаблон без u может вести себя неожиданно.

Когда regexp подходит идеально, а когда лучше выбрать другой инструмент

Regexp идеально подходит для распознавания формализованных текстовых паттернов, но уступает специализированным парсерам там, где данные имеют вложенную структуру и зависят от контекста. Это базовый критерий выбора инструмента.

Регулярные выражения отлично подходят для:

  • артикулов и кодов;
  • простых проверок формата;
  • очистки и нормализации текста;
  • извлечения повторяющихся шаблонов;
  • поиска по логам и журналам событий.

Лучше выбрать другой инструмент для:

  • разбора сложного HTML и XML;
  • анализа JSON;
  • полной проверки URL по спецификации;
  • сценариев, где важны вложенность и контекст.

Здесь полезна аналогия с кухонным ножом. Хороший нож универсален и решает множество задач, но им неудобно откручивать винты и измерять температуру. Точно так же regexp великолепен в текстовых шаблонах, но не должен подменять инструменты, созданные для структурного синтаксического разбора.

Мини-чеклист: как писать понятные и надёжные регулярные выражения

Надёжное регулярное выражение начинается с точной формулировки входного формата и заканчивается проверкой на реальных строках, включая пограничные случаи. Этот подход резко снижает число скрытых ошибок.

  1. Сначала опишите формат словами.
  2. Зафиксируйте начало и конец строки, если нужна валидация.
  3. Экранируйте специальные символы: ., +, (, ), [, ].
  4. Избегайте .*, если можно описать диапазон точнее.
  5. Проверяйте шаблон на негативных примерах, а не только на позитивных.
  6. Используйте именованные группы в длинных выражениях.
  7. Для Unicode-текста включайте u, когда это уместно.
  8. Не пытайтесь regex-ом заменить полноценную бизнес-валидацию.

Согласно State of JS, JavaScript стабильно остаётся одной из самых используемых технологий среди веб-разработчиков, а значит работа со строками, пользовательским вводом, URL и данными форм остаётся повседневной практикой. В такой среде знание regexp — не абстрактный навык, а реальный инструмент экономии времени и снижения числа багов.

Регулярные выражения в JavaScript нужны там, где текст должен подчиняться чёткой форме: от чисел и дат до шаблонов адресов и кодов. Если понимать символы, якоря, квантификаторы, группы и флаги, regexp перестаёт выглядеть как «магическая строка» и превращается в предсказуемый рабочий инструмент. Главное — строить шаблон как точный маршрут с понятным началом, последовательными остановками и строгим концом, а не как набор символов на удачу.

ChatGPT Perplexity Google (AI)