Перейти к основному содержимому

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

Разработчику Инженеру

См. также: глоссарий — регулярные выражения · JavaScript — RegExp · Python — модуль re · Bash — =~ и grep · терминал — grep


RegEx — шаблон для текста

Регулярное выражение (RegEx, regexp) — компактная запись правила поиска и замены в строке. Одним шаблоном можно проверить формат телефона, вытащить дату из лога, отфильтровать строки в grep или задать атрибут pattern в HTML-форме.

Шаблон собирается из литералов (буквы и цифры «как есть») и метасимволов (точка, квантификаторы, классы символов). Движок сопоставляет шаблон с текстом слева направо; при совпадении возвращает фрагмент или группы для подстановки.

Разные «диалекты»

Синтаксис близок во многих языках, но детали расходятся: именованные группы, lookbehind, флаги Unicode. В Python — модуль re (синтаксис близок к Perl); в JavaScript — тип RegExp; в grep по умолчанию — POSIX ERE/BRE. Перед продакшеном сверяйте шаблон с документацией своего движка.

Теоретическая основа — регулярные языки (тип 3 в иерархии Хомского): те же классы строк, что задаёт конечный автомат. RegEx удобны для лексического разбора и валидации форматов, но не заменяют парсеры JSON, HTML или SQL.


Быстрый старт

Типичный цикл из трёх шагов:

  1. Написать простой шаблон и проверить «есть ли совпадение».
  2. Добавить группы (...), если нужно извлечь части строки.
  3. Перейти к замене, когда задача — преобразовать текст, а не только найти.
Телефон: +7 (999) 123-45-67
Шаблон: \D → удалить всё, кроме цифр
Шаблон: ^7\d{10}$ → ровно 11 цифр, первая — 7

В JavaScript тот же приём выглядит как replace(/\D/g, '') и test(/^7\d{10}$/).


Основы

КонструкцияСмысл
.Любой символ, кроме перевода строки (если нет флага «точка = всё», см. ниже)
aСимвол a буквально
abПодстрока ab
a|ba или b
a*Ноль и более a подряд
\Экранирует метасимвол: \. — точка, а не «любой символ»

Литералы совпадают сами с собой. Метасимволы нужно экранировать обратным слешем, если вы хотите их буквальное значение.


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

КонструкцияСмысл
*Ноль и более предыдущего элемента
+Один и более
?Ноль или один
{2}Ровно 2 повторения
{2,5}От 2 до 5 включительно
{2,}Два и более
{,5}До 5 включительно

По умолчанию квантификаторы жадные (greedy): берут максимально длинное совпадение. Ленивый (reluctant) режим — добавить ? после квантификатора: *?, +?, {2,5}? — минимально возможное совпадение.

Пример: в строке <b>жирный</b> шаблон <.*> захватит всё от первого < до последнего >; <.*?> остановится на первом >.


Группы

КонструкцияСмысл
(...)Захватывающая группа — попадает в результат под номером 1, 2, …
(?:...)Группировка без захвата
(?P<имя>...)Именованная группа (Python, часть других движков)
(?<имя>...)Именованная группа (JavaScript)
\1, \2Ссылка на группу по номеру в том же шаблоне
(?P=имя)Совпадение с уже захваченной именованной группой (Python)
(?#комментарий)Комментарий внутри шаблона (Python, флаг x)

Группы нужны и для извлечения данных, и для повторения фрагмента: (\d{2})-\1 найдёт 12-12, если обе части одинаковы.


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

КонструкцияСмысл
[ab-d]Один символ из набора: a, b, c, d
[^ab-d]Один символ вне набора
[\b]Символ backspace (внутри класса)
\dЦифра [0-9]
\DНе цифра
\sПробельный символ (пробел, таб, перевод строки и т.д.)
\SНе пробельный
\w«Словесный» символ (буква, цифра, _; точное определение зависит от движка)
\WНе «словесный»

Внутри [...] большинство метасимволов теряют особый смысл; диапазоны задают через дефис: [A-Za-z0-9_].


Утверждения (assertions)

Утверждения проверяют контекст вокруг совпадения, не расходуя символы входа (кроме lookbehind с переменной длиной в части движков).

КонструкцияСмысл
^Начало строки (или начало строки в режиме многострочности)
$Конец строки
\AНачало всего текста (Python; игнорирует флаг m)
\ZКонец всего текста (Python)
\bГраница слова
\BНе граница слова
(?=...)Позитивный lookahead — дальше должно совпасть ...
(?!...)Негативный lookahead — дальше не должно совпасть
(?<=...)Позитивный lookbehind — слева должно совпасть
(?<!...)Негативный lookbehind

Пример lookahead: пароль с цифрой — ^(?=.*\d).{8,}$ (минимум 8 символов и хотя бы одна цифра где угодно в строке).

Условные конструкции (?(условие)да|нет) есть в расширенных диалектах; в повседневном коде встречаются редко.


Флаги

Флаги задают режим сопоставления. В JavaScript их пишут после литерала /шаблон/flags; в Python — третьим аргументом re.compile(..., flags=re.I) или (?i) внутри шаблона.

ФлагНазначение
iБез учёта регистра
m^ и $ привязаны к строкам внутри многострочного текста
s. совпадает и с переводом строки (JavaScript s, Python re.DOTALL)
xПробелы вне классов игнорируются, допускаются комментарии (?#...)
uUnicode-классы, корректная работа с суррогатными парами
gВсе совпадения, не только первое (JavaScript)
LЛокальные классы символов (редко)

Встроенная установка в шаблоне (Python): (?im) в начале или (?iLmsux-imsx:подшаблон) для части выражения.


Спецсимволы и escape-последовательности

КонструкцияСмысл
\nПеревод строки
\rВозврат каретки
\tТабуляция
\YYYСимвол по восьмеричному коду (зависит от движка)
\xYYСимвол по шестнадцатеричному коду

В строках языка программирования обратный слеш часто экранируется дважды: в Python r"\d+", в JavaScript-строке "\\d+", в литерале RegExp — /\d+/.


Замена и подстановки

При replace / sub в строку подстановки попадают ссылки на группы:

ДвижокВставить всё совпадениеГруппа 1Именованная группа
JavaScript$&$1$<имя>
Python re.sub\g<0>\1\g<имя>
.NET$0$1${имя}
sed (GNU)&\1

В JavaScript колбэк во втором аргументе replace удобен, когда подстановка зависит от логики, а не только от номера группы.


Где применяется в энциклопедии

ОбластьМеханизмСтатья
Клиентский кодRegExp, методы строкRegExp в JavaScript
Скрипты и данныеre.findall, re.subPython — re, pandas — str.contains
Shellgrep, sed, [[ =~ ]]Справочник Linux, Bash
HTML-формыатрибут pattern (подмножество JS RegExp)Справочник <input>
SQLLIKE с % и _не полный RegExОператоры WHERE
Безопасностьвалидация входа, фильтры WAFОсновы ИБ

LIKE в SQL — отдельный мини-язык: % — любая длина, _ — ровно один символ. Для сложных масок в PostgreSQL есть ~ / ~* (POSIX regex); в других СУБД — свои операторы (REGEXP в MySQL и т.д.).


Ограничения и типичные ошибки

Когда RegEx не подходит
  • HTML, XML, JSON — вложенная структура; нужен парсер, а не один большой шаблон.
  • Email и URL «на 100 %» — в продакшене опирайтесь на типы полей HTML, библиотеки и серверную проверку.
  • Катастрофический backtracking — вложенные квантификаторы вроде (a+)+ на длинном вводе «подвешивают» процесс; упрощайте шаблон или ограничивайте длину строки.
ЗадачаРазумный подход
Простая маска (телефон, код)Короткий RegEx + нормализация ввода
Поля формы в браузереtype, pattern, Constraint Validation API
Поиск в логах на сервереgrep -E, при сложной логике — скрипт на Python
Разбор структурированного протоколаПарсер, грамматика, не regexp

Краткий итог

RegEx — шаблон, флаги и операции поиск / проверка / замена. Освойте таблицы основ, квантификаторов и классов символов, затем переходите к языковым статьям: синтаксис групп и подстановок в вашем движке чуть отличается, а идея одна — описать правило текста один раз и переиспользовать в коде, формах и терминале.


См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").