Menu
Русский

Регулярные выражения в Python: модуль re, паттерны, группы и замены

Практическое введение в модуль re — поиск, matching, захватывающие группы, замены и паттерны, к которым будешь тянуться чаще всего.

Когда тянуться к regex

Регулярные выражения — маленький язык для описания текстовых паттернов. Они мощные и легко над-используются.

Прежде чем идти к re, спроси себя, справятся ли обычные методы строк. .split(), .replace(), .startswith(), "target" in text — быстрее, читаемее и менее подвержены ошибкам, чем эквивалентный regex. Оставь regex для случаев, где нужный тебе паттерн действительно структурированный, но слишком гибкий для фиксированных строковых операций: email-ы, номера телефонов, лог-строки с известной формой, HTML или Markdown куски, любой поиск «найди такое-то вот».

Базовый словарь

Regex-паттерн — строка, описывающая то, что ты ищешь. Несколько кирпичиков:

  • . — любой один символ
  • \d — любая цифра (0–9)
  • \w — любой «словесный» символ (буква, цифра, подчёркивание)
  • \s — любой пробельный символ
  • ^ — начало строки
  • $ — конец строки
  • [abc] — один из a, b или c
  • [^abc] — любой символ, кроме a, b, c
  • a|b — a или b
  • * — ноль или больше предыдущего
  • + — один или больше
  • ? — ноль или один
  • {3} — ровно 3
  • {2,5} — от 2 до 5
  • ( ... ) — группа (захватывает совпадение внутри)

Этого хватит на большинство реальных regex-ов.

Ключевые функции

re.search(pattern, text) находит первое совпадение где угодно в строке. Возвращает match-объект или None:

main.py
Output
Click Run to see the output here.

Всегда используй raw-строку (r"...") для regex-паттернов. Иначе Python попытается интерпретировать обратные слэши как строковые escape-ы, и ты получишь другой паттерн, чем задумывал.

re.match(pattern, text) как search, но совпадает только в начале:

main.py
Output
Click Run to see the output here.

Чаще всего нужен search.

re.findall(pattern, text) возвращает все неперекрывающиеся совпадения списком:

main.py
Output
Click Run to see the output here.

Заметь: findall возвращает строки, а не match-объекты. Если в паттерне одна группа — получишь содержимое группы. Несколько групп — список кортежей.

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

Скобки в паттерне захватывают то, что совпало внутри:

main.py
Output
Click Run to see the output here.

Именованные группы обычно читаются лучше:

main.py
Output
Click Run to see the output here.

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

Замена через re.sub

re.sub(pattern, replacement, text) заменяет каждое совпадение:

main.py
Output
Click Run to see the output here.

Вырезает всё, что не цифра. В замене можно ссылаться на захваченные группы через \1, \2 и так далее, а в raw-строках \g<1> яснее:

main.py
Output
Click Run to see the output here.

В качестве замены можно передать и функцию. Удобно для преобразований, не сводящихся к простому обмену:

main.py
Output
Click Run to see the output here.

Компилируем паттерн для переиспользования

Если ты используешь один и тот же паттерн много раз — особенно в цикле, — скомпилируй его один раз:

main.py
Output
Click Run to see the output here.

У скомпилированных паттернов те же методы — search, match, findall, sub — только без паттерна первым аргументом. Чуть эффективнее и часто читаемее.

Флаги

Типичные модификаторы, передаваемые аргументом flags= или соединяемые через |:

  • re.IGNORECASE (re.I) — без учёта регистра.
  • re.MULTILINE (re.M) — ^ и $ совпадают на каждой строке, а не только на границах всей строки.
  • re.DOTALL (re.S) — . совпадает и с переводом строки (по умолчанию — нет).
  • re.VERBOSE (re.X) — разрешает пробелы и #-комментарии в паттерне ради читаемости.
main.py
Output
Click Run to see the output here.

re.VERBOSE особенно удобен для сложных паттернов:

main.py
Output
Click Run to see the output here.

Многострочные закомментированные regex-ы поддерживать гораздо проще, чем непрозрачные однострочники.

Жадные vs ленивые

Квантификаторы (*, +, ?, {n,}) по умолчанию жадные — хватают как можно больше. Добавь ?, чтобы сделать их ленивыми:

main.py
Output
Click Run to see the output here.

Жадная версия захватывает всю подстроку от <b> до </i> — скорее всего, не то, чего ты хотел. Ленивый .+? останавливается на первом >.

(Заметка на полях: реальный HTML regex-ом в продакшене не парсят. Используй html.parser или BeautifulSoup. Пример выше — только ради демонстрации жадности.)

Реалистичный пример

Разбор строк простого лога:

main.py
Output
Click Run to see the output here.

Много мощности в немногих строках.

Несколько привычек

  • Всегда используй raw-строки для паттернов.
  • Начинай с простейшего работающего паттерна; ужесточай потом.
  • Именованные группы — как только групп больше одной.
  • Компилируй паттерны, которые будешь переиспользовать.
  • Regex медленнее обычных методов строк. Если .split() справится — бери .split().

Дальше: ошибки и отладка

Это закрывает тур по реальным данным — файлам, JSON, CSV, HTTP, датам и regex. В любой реальной программе рано или поздно всплывает ошибка, и умение хорошо читать трейсбэки Python — самый большой отладочный навык, который можно развить. Последняя глава — про исключения и конкретные ошибки, которые встречаются чаще всего.

Часто задаваемые вопросы

Что такое regex в Python?

Регулярное выражение (regex) — это маленький язык для описания паттернов в тексте. Модуль re в Python позволяет искать паттерны, извлекать куски и заменять совпадения. Для простых строковых операций это перебор — сначала бери методы строк вроде .split() или .replace(), — но для структурированного поиска regex вне конкуренции.

В чём разница между re.match и re.search?

re.match ищет совпадение только в начале строки. re.search сканирует всю строку и находит первое совпадение где угодно. Сомневаешься — бери search: он ближе к человеческой интуиции.

Всегда ли использовать raw-строки для regex-паттернов?

Да. В regex-паттернах часто есть обратные слэши (\d, \s, \b), которые Python в обычных строках трактует как escape-последовательности. Префикс rr'\d+' — говорит Python брать строку буквально, что оставляет сам regex читаемым.

Учитесь программировать с Coddy

НАЧАТЬ