Regex в Python: шпаргалка
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Основные функции модуля re
import re
re.search(pattern, string) # найти первое совпадение
re.findall(pattern, string) # все совпадения → список
re.finditer(pattern, string) # все → итератор Match-объектов
re.match(pattern, string) # только в начале строки
re.fullmatch(pattern, string) # только если вся строка совпадает
re.sub(pattern, repl, string) # замена
re.split(pattern, string) # разделить по паттерну
re.compile(pattern) # предкомпилировать для переиспользованияМетасимволы
| Символ | Что делает |
|---|---|
. |
любой символ кроме \n |
^ |
начало строки |
$ |
конец строки |
\\d |
цифра [0-9] |
\\D |
не-цифра |
\\s |
пробельный символ |
\\S |
не-пробельный |
\\w |
[A-Za-z0-9_] |
\\W |
не \w |
\\b |
граница слова |
\\B |
не граница слова |
[abc] |
любой из a, b, c |
[^abc] |
любой кроме a, b, c |
[a-z] |
любой в диапазоне |
Квантификаторы
| Значение | |
|---|---|
* |
0 или больше |
+ |
1 или больше |
? |
0 или 1 |
{n} |
ровно n |
{n,} |
n или больше |
{n,m} |
от n до m |
По умолчанию жадные (максимум). *?, +? — ленивые (минимум).
1. Найти email
pattern = r'\b[\w.-]+@[\w.-]+\.\w+\b'
text = "Пиши на alice@example.com или bob@company.ru"
emails = re.findall(pattern, text)
# ['alice@example.com', 'bob@company.ru']2. Найти номер телефона (РФ)
pattern = r'(?:\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}'
text = "+7 (495) 123-45-67 или 8 900 111 22 33"
phones = re.findall(pattern, text)3. Извлечь цифры из строки
text = "Заказ #12345 на 999 рублей"
digits = re.findall(r'\d+', text)
# ['12345', '999']4. Удалить не-буквы
text = "Привет! Как 123 дела?"
clean = re.sub(r'[^\w\s]', '', text)
# 'Привет Как 123 дела'5. Заменить на другую строку
text = "Цена 100 рублей, скидка 10 рублей"
result = re.sub(r'\d+ рублей', 'XXX руб.', text)
# 'Цена XXX руб., скидка XXX руб.'6. Группы через скобки
text = "Иванов Иван Иванович"
m = re.search(r'(\w+)\s+(\w+)\s+(\w+)', text)
m.group(0) # 'Иванов Иван Иванович' (вся совпавшая часть)
m.group(1) # 'Иванов'
m.group(2) # 'Иван'
m.group(3) # 'Иванович'
m.groups() # ('Иванов', 'Иван', 'Иванович')7. Именованные группы
pattern = r'(?P<name>\w+)\s+(?P<age>\d+)'
m = re.search(pattern, "Alice 30")
m.group('name') # 'Alice'
m.group('age') # '30'
m.groupdict() # {'name': 'Alice', 'age': '30'}8. Извлечь дату в разных форматах
pattern = r'(\d{2})[./-](\d{2})[./-](\d{4})'
dates = re.findall(pattern, "Было 12.04.2026, стало 21/04/2026, позже 15-05-2026")
# [('12', '04', '2026'), ('21', '04', '2026'), ('15', '05', '2026')]9. Извлечь UTM-параметры из URL
url = "https://example.com?utm_source=google&utm_medium=cpc&ref=abc"
utm = re.findall(r'utm_(\w+)=([^&]+)', url)
# [('source', 'google'), ('medium', 'cpc')]10. Split по нескольким разделителям
text = "a,b;c.d|e"
parts = re.split(r'[,;.|]', text)
# ['a', 'b', 'c', 'd', 'e']11. Флаги
# игнорировать регистр
re.findall(r'hello', text, flags=re.IGNORECASE)
# многострочный (^ и $ работают для каждой строки)
re.findall(r'^\w+', text, flags=re.MULTILINE)
# . будет матчить и \n
re.findall(r'<div>.*?</div>', html, flags=re.DOTALL)
# комбинировать через |
re.findall(r'\bhello\b', text, flags=re.I | re.M)12. Lookahead / Lookbehind
# перед совпадением: (?<=...)
# после совпадения: (?=...)
# отрицательные: (?<!...) и (?!...)
# цена без валюты
re.findall(r'(?<=цена )\d+', "цена 100, скидка 20")
# ['100']
# число перед рублями
re.findall(r'\d+(?= руб)', "100 руб, 50 долл")
# ['100']13. Применение в pandas
import pandas as pd
df = pd.DataFrame({'text': ['Заказ #12345', 'Счёт #7890']})
# извлечь число
df['order_id'] = df['text'].str.extract(r'#(\d+)')
# заменить
df['text_clean'] = df['text'].str.replace(r'#\d+', 'ORDER', regex=True)
# проверить, содержит ли паттерн
df['has_order'] = df['text'].str.contains(r'#\d+', regex=True)14. Предкомпилировать для скорости
# если используете одно и то же regex много раз
pattern = re.compile(r'\d{4}-\d{2}-\d{2}')
for text in texts:
if pattern.search(text):
...Предкомпиляция ускоряет повторные вызовы в 2-3 раза.
Частые ошибки
Ошибка 1. Забыть raw string
# плохо — \d трактуется как escape-последовательность
re.findall('\d+', text) # предупреждение в новых Python
# правильно
re.findall(r'\d+', text)Всегда используйте r'...' для regex.
Ошибка 2. Жадность там, где не нужна
# жадный — захватит максимум
re.findall(r'<.*>', '<a><b>') # ['<a><b>']
# ленивый — минимум
re.findall(r'<.*?>', '<a><b>') # ['<a>', '<b>']Ошибка 3. Не проверять None
m = re.search(pattern, text)
# если нет совпадения, m = None
value = m.group(1) # AttributeError
# правильно
if m:
value = m.group(1)Ошибка 4. Использовать regex для HTML / JSON
Не пользуйтесь regex для HTML — используйте BeautifulSoup. Для JSON — json.loads. Regex плохо справляется с вложенностью.
Связанные темы
- Python шпаргалка для аналитика
- String функции SQL
- Lambda Python — шпаргалка
- F-string Python — шпаргалка
FAQ
Что такое raw string и зачем он?
r'...' отключает обработку escape-последовательностей. В regex часто встречается \, и без raw-строки Python пытается интерпретировать \d, \s как escape — некорректно.
search vs match vs fullmatch?
match — только в начале строки. fullmatch — вся строка целиком. search — в любом месте.
Когда use re.compile?
Когда паттерн используется много раз в цикле. Иначе — обычной функцией re.findall/search достаточно.
Как запомнить метасимволы?
Мнемоника: \digit (цифра), \space (пробел), \word (слово), \boundary (граница). Заглавные — отрицание.
Тренируйте Python — откройте тренажёр с 1500+ вопросами для собесов аналитиков.