Регулярные выражения в Python — методическое руководство с нуля
- Что такое регулярные выражения
Регулярные выражения (regex) — это способ искать, проверять и изменять текст по шаблону.
Аналогия:
Регулярное выражение — это трафарет.
Текст — это лист бумаги.
Ты прикладываешь трафарет и видишь, где совпадает рисунок.
Примеры задач:
- найти все номера телефонов
- проверить правильность email
- вытащить дату из текста
- заменить лишние символы
- разбить строку по шаблону
⸻
- Модуль re — основной инструмент
В Python регулярные выражения находятся в модуле:
import re
Основные функции:
re.search() # ищет первое совпадение
re.match() # проверяет начало строки
re.findall() # находит все совпадения
re.sub() # заменяет текст
re.split() # разбивает строку
⸻
- Первый пример — поиск слова
import re
text = "Я люблю Python"
result = re.search("Python", text)
print(result)
Результат:
<re.Match object>
Если не найдено:
None
⸻
- Простые символы — точное совпадение
Если написать:
re.search("cat", "I have a cat")
Будет найдено cat.
Но:
re.search("cat", "catalog")
Тоже найдёт — потому что cat внутри слова.
⸻
- Специальные символы — основа regex
. — любой символ
re.search("c.t", "cat")
re.search("c.t", "cut")
re.search("c.t", "c9t")
Совпадения:
cat
cut
c9t
Аналогия:
. — это любой символ на этом месте.
⸻
^ — начало строки
re.search("^cat", "cat is here")
Совпадение есть.
re.search("^cat", "my cat")
Совпадения нет.
⸻
$ — конец строки
re.search("cat$", "my cat")
Совпадение есть.
⸻
- Классы символов [ ]
Позволяют выбирать символы.
re.search("c[ao]t", "cat")
re.search("c[ao]t", "cot")
Совпадения:
cat
cot
Но:
re.search("c[ao]t", "cut")
Нет совпадения.
⸻
Диапазоны
[a-z] # все маленькие буквы
[A-Z] # большие буквы
[0-9] # цифры
Пример:
re.search("[0-9]", "abc3def")
Найдёт:
3
⸻
Отрицание [ ^ ]
[^0-9]
Означает:
любой символ кроме цифры
Пример:
re.search("[^0-9]", "123a")
Найдёт:
a
⸻
- Готовые классы
Очень важные:
\d # цифра [0-9]
\w # буква или цифра
\s # пробел
Обратные:
\D # не цифра
\W # не буква
\S # не пробел
⸻
Пример:
re.findall(r"\d", "a1b2c3")
Результат:
['1', '2', '3']
Обрати внимание:
r"\d"
r означает сырая строка (raw string).
Без неё:
"\d"
может работать неправильно.
⸻
- Повторы — квантификаторы
Очень важный блок.
⸻
- — 0 или больше
ab*
Совпадает:
a
ab
abb
abbb
⸻
- — 1 или больше
ab+
Совпадает:
ab
abb
abbb
Но не:
a
⸻
? — 0 или 1
ab?
Совпадает:
a
ab
⸻
{n} — ровно n
\d{3}
Совпадает:
123
456
⸻
{n,m} — диапазон
\d{2,4}
Совпадает:
12
123
1234
⸻
- Группы ( )
Используются для:
- выделения части совпадения
- повторов
- логики
⸻
Пример:
text = "Дата: 12-05-2024"
result = re.search(r"(\d{2})-(\d{2})-(\d{4})", text)
print(result.groups())
Результат:
('12', '05', '2024')
Теперь можно работать отдельно:
day = result.group(1)
month = result.group(2)
year = result.group(3)
⸻
- Альтернатива |
Означает или.
re.search("cat|dog", "I have a dog")
Найдёт:
dog
⸻
- Основные функции re
⸻
re.findall() — найти всё
text = "Телефоны: 123, 456, 789"
numbers = re.findall(r"\d+", text)
print(numbers)
Результат:
['123', '456', '789']
⸻
re.search() — первое совпадение
re.search(r"\d+", "abc123xyz")
⸻
re.match() — только начало строки
re.match(r"\d+", "123abc") # есть
re.match(r"\d+", "abc123") # нет
⸻
re.sub() — замена
text = "Цена: 100 руб"
result = re.sub(r"\d+", "XXX", text)
print(result)
Результат:
Цена: XXX руб
⸻
re.split() — разделение
text = "яблоко,груша,банан"
result = re.split(",", text)
print(result)
Результат:
['яблоко', 'груша', 'банан']
⸻
- Реальные практические примеры
⸻
Проверка email
Простой шаблон:
pattern = r"\w+@\w+.\w+"
email = "test@mail.com"
if re.match(pattern, email):
print("OK")
⸻
Поиск телефона
text = "Мой номер: +7-999-123-45-67"
phones = re.findall(r"+\d-\d{3}-\d{3}-\d{2}-\d{2}", text)
print(phones)
⸻
Извлечение даты
text = "Сегодня 12.05.2024"
date = re.search(r"\d{2}.\d{2}.\d{4}", text)
print(date.group())
⸻
Удаление лишних пробелов
text = "Hello world"
result = re.sub(r"\s+", " ", text)
print(result)
Результат:
Hello world
⸻
- Жадность (Greedy) — важная тема
По умолчанию regex жадный.
Берёт максимум.
⸻
Пример:
text = "text"
re.findall(r"<.*>", text)
Результат:
['text']
⸻
Ленивый режим ?
re.findall(r"<.*?>", text)
Результат:
['', '']
⸻
Аналогия:
- .* — загребает всё
- .*? — берёт минимум
⸻
- Флаги (режимы)
Используются как параметр.
⸻
re.IGNORECASE
Игнорирует регистр.
re.search("python", "Python", re.IGNORECASE)
⸻
re.MULTILINE
Работа со строками в несколько строк.
re.search("^cat", text, re.MULTILINE)
⸻
re.DOTALL
. включает перенос строки.
⸻
- Компиляция шаблона
Если используется много раз:
pattern = re.compile(r"\d+")
pattern.findall("123 abc 456")
Быстрее при повторных вызовах.
⸻
- Типовые шаблоны (шпаргалка)
Email:
r"\w+@\w+.\w+"
Дата:
r"\d{2}.\d{2}.\d{4}"
Телефон:
r"+\d{1,3}-\d{3}-\d{3}-\d{2}-\d{2}"
IP:
r"\d{1,3}(.\d{1,3}){3}"
⸻
- Как мыслить при написании regex
Алгоритм:
-
Определи цель
Что ищем. -
Разбей на части
Например:12.05.2024
Разбор:
2 цифры
.
2 цифры
.
4 цифры
Regex:
\d{2}.\d{2}.\d{4}
⸻
-
Частые ошибки
-
Забыт r перед строкой
Неправильно:
"\d+"
Правильно:
r"\d+"
⸻
- Точка без экранирования
.
Означает любой символ.
Если нужна точка:
.
⸻
- Неправильные квантификаторы
\d+
может взять слишком много.
Иногда нужно:
\d{2}
⸻
- Практические задания
Задание 1
Найти все числа:
abc123xyz456
Решение:
re.findall(r"\d+", text)
⸻
Задание 2
Проверить дату:
31.12.2024
Regex:
r"\d{2}.\d{2}.\d{4}"
⸻
Задание 3
Удалить все символы кроме букв:
re.sub(r"[^a-zA-Z]", "", text)
⸻
- Итоговая структура знаний
Освоить:
- Символы
. ^ $ - Классы
[ ] - Готовые классы
\d \w \s - Повторы
-
- ? {}
-
- Группы
( ) - Функции
findall search sub split
После этого можно решать большинство задач обработки текста.