Регулярные выражения
Регулярное выражение (regex) — строка-шаблон, описывающая множество строк, по которой ищут, проверяют и заменяют текст.
Что такое Регулярные выражения
Регулярное выражение (regex, regexp, в разговоре «регулярка») — строка-шаблон, описывающая множество строк. Вместо перечисления «найди 8-800-555-35-35 или 8-800-555-35-36 или…» шаблон задаёт правило: «восьмёрка, дефис, три цифры, дефис…».
Три типовые задачи: найти подстроку по образцу, проверить формат ввода, заменить по шаблону. Движки regex встроены почти везде — Python, JavaScript, grep, sed, PHP, Java, PostgreSQL, конфиги Nginx. Термин пришёл из теории формальных языков, где «регулярный» — класс языков, распознаваемых конечным автоматом; современные движки давно вышли за эти рамки, но название осталось.
Базовый синтаксис
| Шаблон | Значение | Пример совпадения |
|---|---|---|
. |
Любой символ, кроме перевода строки | a.c → abc, a7c |
\d \w \s |
Цифра, буквоцифра/_, пробельный |
\d\d → 42 |
\D \W \S |
Отрицание предыдущих | \D → x |
[abc] |
Любой из перечисленных | [аеиоу] → гласная |
[^abc] |
Любой, кроме перечисленных | [^0-9] → не цифра |
[a-z] |
Диапазон | [a-zA-Zа-яА-Я] |
^ $ |
Начало и конец строки | ^Ошибка |
\b |
Граница слова | \bкот\b не найдёт «котлета» |
| |
Или | cat|dog |
(...) |
Группа с захватом | (\d{4})-(\d{2}) |
(?:...) |
Группа без захвата | (?:ab)+ |
Квантификаторы — сколько раз
| Шаблон | Сколько | Пример |
|---|---|---|
* |
0 или больше | \d* |
+ |
1 или больше | \d+ → 2026 |
? |
0 или 1 | https? → http, https |
{3} |
Ровно 3 | \d{3} |
{2,5} |
От 2 до 5 | \w{2,5} |
{2,} |
2 и больше | \d{2,} |
Жадность — источник половины багов
По умолчанию квантификаторы жадные: берут максимум возможного, потом отдают назад по мере необходимости.
import re
html = "<b>жирный</b> и <i>курсив</i>"
re.findall(r"<.+>", html) # ['<b>жирный</b> и <i>курсив</i>'] — съел всё
re.findall(r"<.+?>", html) # ['<b>', '</b>', '<i>', '</i>'] — ленивый, минимум
? после квантификатора делает его ленивым. Ещё надёжнее — запретить лишнее явно: <[^>]+> вообще не даст точке перепрыгнуть через >.
Практика на Python
import re
text = "Заказ 8814 от 2026-07-17, сумма 15000 руб., ivan@example.com"
re.search(r"\d{4}-\d{2}-\d{2}", text).group() # '2026-07-17'
re.findall(r"\d+", text) # ['8814', '2026', '07', '17', '15000']
re.sub(r"\d{4}-\d{2}-\d{2}", "<дата>", text) # замена
re.split(r",\s*", text) # разбиение по шаблону
# именованные группы читаются куда лучше, чем m.group(1)
m = re.match(r"(?P<year>\d{4})-(?P<month>\d{2})", "2026-07")
m.group("year") # '2026'
# компиляция — если шаблон применяется в цикле
pattern = re.compile(r"^ERROR\s+(\S+)", re.MULTILINE)
Флаги: re.IGNORECASE — без учёта регистра, re.MULTILINE — ^/$ работают на каждой строке, re.VERBOSE — разрешает пробелы и комментарии внутри шаблона.
Те же шаблоны работают в Bash через grep — например, топ IP-адресов из лога:
grep -Eo '[0-9]{1,3}(\.[0-9]{1,3}){3}' access.log | sort | uniq -c | sort -rn
ReDoS — регулярка как способ уронить сервер
Вложенные квантификаторы приводят к катастрофическому бэктрекингу: движок перебирает экспоненциальное число вариантов, и один запрос занимает ядро CPU на минуты.
re.match(r"^(a+)+$", "a" * 30 + "!") # зависнет надолго
Если шаблон применяется к пользовательскому вводу, это готовая уязвимость — ReDoS. Меры: не вкладывать квантификатор в квантификатор, ограничивать длину входа, а в критичных местах брать движок с линейной гарантией (RE2, regex с таймаутом).
Когда не надо
- HTML и XML — вложенность регуляркой не разбирается в принципе. Берите парсер (BeautifulSoup, lxml).
- JSON, CSV — есть готовые библиотеки, они учитывают кавычки и экранирование.
- Email по-настоящему — полный шаблон из RFC 5322 занимает страницу. Проверьте наличие
@и отправьте письмо со ссылкой подтверждения; это единственная надёжная валидация. - Простой поиск подстроки —
"error" in lineбыстрее и понятнее любой регулярки.
Отлаживать шаблоны удобно на regex101.com: он показывает разбор по шагам и подсвечивает группы. И помните: regex, который вы писали полчаса, через месяц не прочитает никто — включая вас. Комментируйте (re.VERBOSE) или разбивайте на части.
Связанные термины
- grep — регулярки в командной строке
- Python — модуль re
- Bash — grep, sed и awk в скриптах
- Парсинг — где regex помогает, а где нужен парсер
- Конкатенация — соседняя базовая операция над строками
Готовы запустить GPU-задачу?
Запустить GPU-сервер