Регулярки в Python для начинающих: пять рабочих шаблонов
Пять готовых шаблонов на модуле re: e-mail, телефон, дата, поиск чисел и замена по маске. Копируете, запускаете, разбираетесь на живых примерах примерно за час.

К концу этой инструкции у вас будут пять рабочих шаблонов на регулярных выражениях: проверка e-mail, извлечение телефона из текста, разбор даты, поиск всех чисел в строке и замена по маске. Каждый фрагмент запускается как есть — скопировали в файл, выполнили, увидели результат. На весь разбор уйдёт примерно час, если вы раньше не видели ни одной регулярки.
Регулярное выражение1 — это строка-шаблон, по которой Python ищет совпадения в тексте. Работает через встроенный модуль re, ставить ничего не нужно.
Что нужно до начала
- Python 3.8 или новее. Проверьте командой
python --versionв терминале. Все примеры ниже работают и на 3.8, и на 3.12. - Модуль
re. Он входит в стандартную библиотеку — отдельно устанавливать не надо, просто пишетеimport re. - Любой редактор. Хоть встроенный IDLE, хоть VS Code. Каждый пример — самодостаточный файл.
Одно правило, которое сэкономит вам час отладки: шаблоны всегда пишите как raw-строку с префиксом r, например r"\d+". Без r Python сначала попытается сам обработать обратные слэши, и \d может сломаться. С r строка уходит в re как есть.
Шаг 1. Проверить e-mail
Начнём с самого частого: пользователь ввёл почту, надо понять, похожа ли она на адрес. Полностью валидировать e-mail по стандарту регуляркой не стоит — это огромное выражение, которое всё равно пропускает крайние случаи. Для формы регистрации достаточно проверки «есть текст, собака, домен с точкой».
import re
# Шаблон: непустое имя, @, домен, точка, зона из 2+ букв
pattern = r"^[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}$"
emails = ["anna@example.com", "плохой@", "user.name+tag@mail.ru"]
for email in emails:
if re.match(pattern, email):
print(f"{email} — похоже на почту")
else:
print(f"{email} — не подходит")Что получится: первая и третья строки пройдут, вторая — нет. Разберём шаблон по кускам:
^и$— начало и конец строки. Без них совпадение может найтись в середине мусора.[\w.+-]+— одна или больше букв, цифр, точек, плюсов и дефисов до собаки.@— сама собака, буквально.[\w-]+\.[a-zA-Z]{2,}— домен, точка, зона из двух и более букв.
re.match проверяет совпадение с начала строки. Именно поэтому здесь он, а не re.search.
Шаг 2. Вытащить телефон из текста
Задача другая: в письме где-то есть номер, надо его достать. Российские номера пишут по-разному — +7, 8, со скобками, с дефисами. Шаблон учитывает эти варианты и вытаскивает цифры.
import re
text = "Звоните: +7 (912) 345-67-89 или пишите на почту"
# Гибкий шаблон под российские номера
pattern = r"(?:\+7|8)[\s(]*\d{3}[\s)]*\d{3}[\s-]*\d{2}[\s-]*\d{2}"
match = re.search(pattern, text)
if match:
raw = match.group()
# Оставляем только цифры
digits = re.sub(r"\D", "", raw)
print("Нашли:", raw)
print("Только цифры:", digits)Что получится: Нашли: +7 (912) 345-67-89 и Только цифры: 79123456789. Здесь важны две вещи. re.search ищет совпадение в любом месте строки, а не только в начале. А (?:...) — это группа без захвата: она нужна для «или» между +7 и 8, но сама в результат не попадает.
Нормализацию сделали отдельным шагом через re.sub(r"\D", "", raw) — заменили всё, что не цифра, на пустую строку. Так удобнее: сначала найти по-человечески написанный номер, потом привести к единому виду для базы.
Шаг 3. Разобрать дату на части
Дата 15.03.2024 — и вам нужны отдельно день, месяц, год. Тут пригодятся группы захвата: части шаблона в круглых скобках, к которым потом обращаешься по номеру или имени.
import re
date_str = "Событие состоится 15.03.2024 в офисе"
# Именованные группы: (?P<имя>...)
pattern = r"(?P\d{2})\.(?P\d{2})\.(?P\d{4})"
match = re.search(pattern, date_str)
if match:
print("День:", match.group("day"))
print("Месяц:", match.group("month"))
print("Год:", match.group("year"))Что получится: три строки с 15, 03 и 2024. Именованные группы (?P<day>...) читаются лучше, чем номера group(1), group(2) — через полгода вы поймёте свой же код. Обратите внимание: точки в шаблоне экранированы как \., потому что голая точка в регулярках означает «любой символ».
Регулярка находит строку, похожую на дату, но не проверяет, что дата существует.32.13.2024шаблон пропустит спокойно. Проверку на осмысленность делайте отдельно — черезdatetime.strptime, который выбросит исключение на несуществующей дате.
Шаг 4. Найти все числа в строке
В отчёте разбросаны суммы, надо собрать их все. Здесь пригодится re.findall — он возвращает список всех совпадений, а не первое.
import re
text = "Заказ 3 позиции на 1500 рублей, скидка 10 процентов"
# Все последовательности из одной и более цифр
numbers = re.findall(r"\d+", text)
print(numbers) # ['3', '1500', '10']
# Если нужны числа как int
numbers_int = [int(n) for n in numbers]
print(sum(numbers_int)) # 1513Что получится: список строк ['3', '1500', '10'], а после преобразования — сумма 1513. findall отдаёт именно строки, поэтому арифметику делаете уже после int(). Если в тексте попадаются числа с точкой — 19.99 — расширьте шаблон до r"\d+(?:\.\d+)?": целая часть, а дальше необязательная дробная.
Шаг 5. Замена по маске
Последний шаблон — скрыть часть данных. Например, в логах нельзя оставлять полные телефоны, надо заменить середину на звёздочки. Здесь re.sub работает с функцией-заменой.
import re
log = "Клиент 79123456789 оформил заказ"
def mask_phone(match):
digits = match.group()
# Оставляем первые 3 и последние 2 цифры
return digits[:3] + "*" * (len(digits) - 5) + digits[-2:]
masked = re.sub(r"\d{11}", mask_phone, log)
print(masked) # Клиент 791******89 оформил заказЧто получится: Клиент 791******89 оформил заказ. Вторым аргументом re.sub принимает не только строку, но и функцию: она получает объект совпадения и возвращает то, чем его заменить. Так вы делаете замену, которая зависит от найденного текста, — фиксированной строкой тут не обошлись бы.
Если не получилось
re.error: bad escapeили странное поведение слэшей. Вы забыли префиксrу шаблона. Пишитеr"\d+", а не"\d+".AttributeError: 'NoneType' object has no attribute 'group'. Совпадения не нашлось,re.searchвернулNone, а вы сразу вызвали.group(). Всегда проверяйте результат черезif match:перед обращением к нему.- Находит не то или слишком много. Скорее всего, забыли
^и$при проверке всей строки, и совпадение нашлось в середине. Для валидации целого значения обрамляйте шаблон якорями. - Точка ловит лишнее. Голая
.— это «любой символ». Если нужна именно точка, экранируйте:\.. - Кириллица не попадает в
\w. В Python 3 по умолчанию\wуже включает буквы Unicode, включая русские. Если вдруг нужны только латинские — используйте флагre.ASCII.
Что дальше
Эти пять шаблонов закрывают большую часть повседневных задач. Дальше стоит освоить две вещи. Первая — компиляция шаблона через re.compile: если один и тот же шаблон применяется в цикле тысячи раз, компиляция один раз заметно быстрее. Вторая — интерактивная отладка на сайте regex101 с режимом Python: вставляете шаблон и текст, и он подсвечивает, что и почему совпало. Именно так проще всего понять, где регулярка ведёт себя не так, как вы ожидали.
Официальный разбор всех спецсимволов и флагов — в документации модуля re. Держите её открытой, пока не запомните основные обозначения наизусть.
1 Регулярное выражение (regex) — формальный язык описания текстовых шаблонов. Одной строкой задаёте правило («две цифры, точка, две цифры»), и движок ищет в тексте всё, что этому правилу соответствует.
Поиск источников: Реальные статьи и книги со ссылками, библиография по ГОСТ
Спросить за 15 ₽Источники: re — Regular expression operations, документация Python, Regular Expression HOWTO, документация Python
Частые вопросы
У меня Python 3.7, примеры сработают?
Чем re.match отличается от re.search?
Регулярка находит совпадение, но group() падает с ошибкой NoneType
Можно ли регуляркой полностью проверить корректность e-mail?
Почему кириллица иногда не попадает в \w?
Стоит ли использовать re.compile?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.