Регулярные выражения в Python
Шпаргалка по регулярным выражениям в Python: модуль re, метасимволы, классы, группы, якоря, флаги и готовые примеры (email, телефон, дата).
Краткая выжимка по регулярным выражениям в Python: модуль re, метасимволы, классы символов, группы, якоря, флаги и готовые рецепты для email, телефона и даты. Все шаблоны записаны в raw-строках r"...".
Модуль re и основные функции
Регулярные выражения в Python живут в стандартном модуле re. Шаблоны принято записывать в raw-строках r"...", чтобы обратные слэши не конфликтовали с escape-последовательностями Python.
| Функция | Что делает |
|---|---|
re.match(p, s) | Ищет совпадение только в начале строки |
re.search(p, s) | Ищет первое совпадение в любом месте строки |
re.findall(p, s) | Возвращает список всех совпадений |
re.finditer(p, s) | Возвращает итератор объектов Match |
re.sub(p, r, s) | Заменяет все совпадения на строку r |
re.split(p, s) | Разбивает строку по шаблону |
re.compile(p) | Компилирует шаблон для повторного использования |
import re
text = "Заказ №42 на сумму 1500 руб"
re.match(r"Заказ", text) # совпадение в начале ->
re.search(r"\\d+", text) # первое число -> Match '42'
re.findall(r"\\d+", text) # все числа -> ['42', '1500']
re.sub(r"\\d+", "#", text) # 'Заказ №# на сумму # руб'
re.split(r"\\s+", "a b c") # ['a', 'b', 'c']
Объект Match и группы
Функции match и search возвращают объект Match (или None, если совпадения нет). Из него достают текст и позиции.
m = re.search(r"(\\d+) руб", "Цена 1500 руб")
if m:
m.group(0) # '1500 руб' — всё совпадение
m.group(1) # '1500' — первая группа
m.start() # 5 — индекс начала
m.span() # (5, 13) — границы совпадения
Компиляция и переиспользование
Если шаблон применяется много раз, выгодно скомпилировать его один раз через re.compile.
digits = re.compile(r"\\d+")
digits.findall("a1 b22 c333") # ['1', '22', '333']
digits.sub("N", "год 2026") # 'год N'
Метасимволы
Метасимволы — это спецсимволы, задающие шаблон, а не буквальный текст. Чтобы найти сам метасимвол (например точку), его экранируют обратным слэшем: \\.
| Символ | Значение |
|---|---|
. | Любой символ, кроме перевода строки |
^ | Начало строки |
$ | Конец строки |
* | 0 или более повторений |
+ | 1 или более повторений |
? | 0 или 1 повторение |
{n} | Ровно n повторений |
{n,m} | От n до m повторений |
| | Альтернатива «или» |
[...] | Любой символ из набора |
re.findall(r"a.c", "abc a c axc") # ['abc', 'a c', 'axc']
re.findall(r"go+gle", "gogle google gooogle")
# ['gogle', 'google', 'gooogle']
re.findall(r"\\d{2,4}", "1 22 333 44444") # ['22', '333', '4444']
re.findall(r"кот|пёс", "кот и пёс") # ['кот', 'пёс']
re.findall(r"3\\.14", "3.14 и 3x14") # ['3.14'] — точка экранирована
Классы символов
Классы — короткие обозначения для групп символов. Заглавная версия означает отрицание (всё, кроме).
| Класс | Значение |
|---|---|
\\d | Цифра [0-9] |
\\D | Не цифра |
\\w | Буква, цифра или _ |
\\W | Не «словесный» символ |
\\s | Пробельный символ (пробел, таб, перенос) |
\\S | Не пробельный символ |
[a-z] | Диапазон символов |
[^abc] | Любой символ, кроме a, b, c |
re.findall(r"\\w+", "hello_world 2026!") # ['hello_world', '2026']
re.findall(r"\\D+", "abc123def") # ['abc', 'def']
re.findall(r"[аеёиоуыэюя]", "привет") # ['и', 'е'] — гласные
re.findall(r"[^0-9 ]", "a1 b2") # ['a', 'b']
Важно: по умолчанию \\w в Python 3 захватывает и буквы Юникода, поэтому русские слова матчатся без дополнительных настроек.
Группы и именованные группы
Круглые скобки (...) создают группу: её можно извлечь отдельно, повторить или подставить в замену. (?:...) — группа без захвата.
m = re.search(r"(\\d{4})-(\\d{2})-(\\d{2})", "Дата: 2026-06-16")
m.groups() # ('2026', '06', '16')
m.group(2) # '06'
# Группа без захвата (?:...)
re.findall(r"(?:https?://)?(\\w+\\.ru)", "http://codechick.ru")
# ['codechick.ru']
Именованные группы
Синтаксис (?P<имя>...) делает шаблон читаемее, а доступ — по имени.
m = re.search(r"(?P<year>\\d{4})-(?P<month>\\d{2})", "2026-06")
m.group("year") # '2026'
m.group("month") # '06'
m.groupdict() # {'year': '2026', 'month': '06'}
# Обратная ссылка на группу: повтор слова
re.findall(r"(\\w+) \\1", "так так бывает") # ['так']
Якоря и границы слова
Якоря не совпадают с символами — они привязываются к позициям. \\b отмечает границу слова, \\B — её отсутствие.
| Якорь | Значение |
|---|---|
^ | Начало строки (или строки при re.M) |
$ | Конец строки (или строки при re.M) |
\\b | Граница слова |
\\B | Не граница слова |
\\A | Начало всего текста |
\\Z | Конец всего текста |
re.findall(r"\\bкот\\b", "кот котёнок кот") # ['кот', 'кот']
re.findall(r"\\d+$", "строка 42") # ['42'] — число в конце
bool(re.search(r"^Hello", "Hello world")) # True
Жадность и ленивость
По умолчанию квантификаторы * + ? {} жадные — берут максимум символов. Добавив ? после квантификатора, делаем его ленивым — берёт минимум.
html = "<b>жирный</b> текст"
re.findall(r"<.*>", html) # ['<b>жирный</b>'] — жадный, захватил всё
re.findall(r"<.*?>", html) # ['<b>', '</b>'] — ленивый, по минимуму
Правило: жадный .* часто «съедает лишнее». Если нужен минимальный фрагмент до ближайшего разделителя — используйте ленивый .*? или явный класс [^>]*.
Флаги
Флаги меняют поведение шаблона. Их передают параметром flags= или объединяют через |.
| Флаг | Действие |
|---|---|
re.I (IGNORECASE) | Игнорировать регистр |
re.M (MULTILINE) | ^ и $ работают на каждой строке |
re.S (DOTALL) | . совпадает и с переводом строки |
re.X (VERBOSE) | Разрешает пробелы и комментарии в шаблоне |
re.findall(r"python", "Python PYTHON", re.I) # ['Python', 'PYTHON']
text = "строка1\\nстрока2\\nстрока3"
re.findall(r"^строка\\d", text, re.M) # ['строка1', 'строка2', 'строка3']
# re.X: читаемый шаблон с комментариями
phone = re.compile(r"""
\\+7 # код страны
\\d{10} # десять цифр номера
""", re.X)
phone.findall("+79991234567") # ['+79991234567']
Практические примеры
Готовые рецепты для частых задач. Под учебные цели подходят, но для строгой валидации (особенно email) лучше использовать специализированные библиотеки.
pattern = r"[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}"
re.findall(pattern, "Пишите на [email protected] или [email protected]")
# ['[email protected]', '[email protected]']
Телефон (российский формат)
pattern = r"(?:\\+7|8)[\\s-]?\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{2}[\\s-]?\\d{2}"
re.findall(pattern, "Тел: +7 (999) 123-45-67 и 89001112233")
# ['+7 (999) 123-45-67', '89001112233']
Дата ДД.ММ.ГГГГ
pattern = r"\\b(\\d{2})\\.(\\d{2})\\.(\\d{4})\\b"
m = re.search(pattern, "Дедлайн 16.06.2026 года")
m.groups() # ('16', '06', '2026')
m.group(0) # '16.06.2026'
Извлечение чисел (включая дробные)
re.findall(r"-?\\d+(?:\\.\\d+)?", "t = -3.5, x=10, y = 0.25")
# ['-3.5', '10', '0.25']
Очистка строки от лишних пробелов
re.sub(r"\\s+", " ", "много пробелов\\tи\\nтабов").strip()
# 'много пробелов и табов'
Шпаргалка-минимум
- Всегда пиши шаблон в raw-строке:
r"\\d+", а не"\\d+". searchищет где угодно,match— только с начала.findallс группами вернёт кортежи групп, а не всё совпадение.- Делай квантификатор ленивым через
?, если жадный «съедает лишнее». - Экранируй спецсимволы:
\\. \\( \\) \\[ \\] \\+ \\* \\? - Компилируй часто используемые шаблоны через
re.compile.