Python - Регулярные выражения
Приветствуем, будущие маги Python! Сегодня мы отправляемся в захватывающее путешествие в мир регулярных выражений (regex) в Python. Не волнуйтесь, если вы никогда не слышали о regex раньше - к концу этого урока вы сможете мастерски использовать этот мощный инструмент!

Что такое регулярные выражения?
Перед тем как погружаться в тему, давайте понимем, что такое регулярные выражения. Представьте себе, что вы детектив, который пытается найти определенный шаблон в море текста. Регулярные выражения - это как ваше увеличительное стекло, помогающее искать и манипулировать строками на основе шаблонов. Круто, правда?
Сырые строки
В Python, работая с regex, мы часто используем сырые строки. Они начинаются с символа 'r' и обрабатывают символы обратной косой черты как литеральные символы. Это особенно полезно в regex, так как обратные косые черты встречаются часто.
# Обычная строка
print("Hello\nWorld")
# Сырая строка
print(r"Hello\nWorld")
В первом случае вы увидите "Hello" и "World" на разных строках. Во втором случае вы увидите "Hello\nWorld" как есть. Это становится критически важным при работе с шаблонами regex.
Метасимволы
Метасимволы - это строительные блоки regex. У них есть особое значение, и они помогают нам определять шаблоны. Давайте рассмотрим некоторые из них:
| Метасимвол | Значение |
|---|---|
| . | Совпадает с любым символом, кроме новой строки |
| ^ | Совпадает с началом строки |
| $ | Совпадает с концом строки |
| * | Совпадает 0 или более повторений |
| + | Совпадает 1 или более повторений |
| ? | Совпадает 0 или 1 повторение |
| {} | Совпадает с явно указанным количеством повторений |
| [] | Указывает набор символов для совпадения |
| \ | Экранирует специальные символы |
Функция re.match()
Функция re.match() пытается найти совпадение шаблона в начале строки. Если она находит совпадение, она возвращает объект совпадения; в противном случае возвращает None.
import re
result = re.match(r"Hello", "Hello, World!")
if result:
print("Совпадение найдено:", result.group())
else:
print("Нет совпадения")
Это выведет "Совпадение найдено: Hello". Метод group() возвращает совпадающую подстроку.
Функция re.search()
В то время как re.match() ищет совпадение в начале строки, re.search() сканирует всю строку для поиска совпадения.
import re
result = re.search(r"World", "Hello, World!")
if result:
print("Совпадение найдено:", result.group())
else:
print("Нет совпадения")
Это выведет "Совпадение найдено: World".
Сравнение match() и search()
Основное различие между match() и search() заключается в том, что match() проверяет совпадение только в начале строки, в то время как search() проверяет совпадение где угодно в строке.
Функция re.findall()
Функция re.findall() возвращает все не перекрывающиеся совпадения шаблона в строке в виде списка.
import re
text = "The rain in Spain falls mainly in the plain"
result = re.findall(r"ain", text)
print(result)
Это выведет ['ain', 'ain', 'ain'].
Функция re.sub()
Функция re.sub() заменяет все вхождения шаблона в строке на строку замены.
import re
text = "The rain in Spain"
result = re.sub(r"a", "o", text)
print(result)
Это выведет "The roin in Spoin".
Функция re.compile()
Функция re.compile() создает объект regex для повторного использования, что может быть более эффективным, если вы используете один и тот же шаблон многократно.
import re
pattern = re.compile(r"\d+")
result1 = pattern.findall("There are 123 apples and 456 oranges")
result2 = pattern.findall("I have 789 bananas")
print(result1)
print(result2)
Это выведет ['123', '456'] и ['789'].
Функция re.finditer()
Функция re.finditer() возвращает итератор, выдающий объекты совпадения для всех не перекрывающихся совпадений шаблона в строке.
import re
text = "The rain in Spain"
for match in re.finditer(r"ain", text):
print(f"Найдено '{match.group()}' в позиции {match.start()}-{match.end()}")
Это выведет:
Найдено 'ain' в позиции 5-8
Найдено 'ain' в позиции 17-20
Примеры использования Python Regex
Регулярные выражения имеют множество практических применений. Рассмотрим общий случай использования:
Найти слова, начинающиеся с гласных
import re
text = "An apple a day keeps the doctor away"
vowel_words = re.findall(r'\b[aeiouAEIOU]\w+', text)
print(vowel_words)
Это выведет ['An', 'apple', 'a', 'away'].
Модификаторы регулярных выражений: флаги опций
Модуль re Python предоставляет несколько флагов опций, которые изменяют интерпретацию шаблонов:
| Флаг | Описание |
|---|---|
| re.IGNORECASE (re.I) | выполняет нечувствительное к регистру сравнение |
| re.MULTILINE (re.M) | делает ^ совпадающим с началом каждой строки и $ концом каждой строки |
| re.DOTALL (re.S) | делает . совпадающим с любым символом, включая новую строку |
| re.VERBOSE (re.X) | позволяет писать более читаемые шаблоны regex |
Регулярные выражения шаблонов
Рассмотрим некоторые более сложные шаблоны:
Классы символов
Классы символов позволяют указывать набор символов для совпадения:
import re
text = "The quick brown fox jumps over the lazy dog"
result = re.findall(r"[aeiou]", text)
print(result)
Это выведет все гласные буквы, найденные в тексте.
Специальные классы символов
Python regex поддерживает специальные классы символов:
| Класс | Описание |
|---|---|
| \d | совпадает с любым десятичным числом |
| \D | совпадает с любым нецифровым символом |
| \s | совпадает с любым пробельным символом |
| \S | совпадает с любым не пробельным символом |
| \w | совпадает с любым буквенно-цифровым символом |
| \W | совпадает с любым не буквенно-цифровым символом |
Повторения
Мы можем указать, сколько раз должен встречаться шаблон:
import re
text = "I have 111 apples and 22 oranges"
result = re.findall(r"\d{2,3}", text)
print(result)
Это выведет ['111', '22'], совпадая с числами с 2 или 3 цифрами.
Ненасыщенные повторения
По умолчанию повторение является насыщенным, то есть совпадает с максимально возможным количеством повторений. Добавление ? после повторения делает его ненасыщенным:
import re
text = "<h1>Title</h1><p>Paragraph</p>"
greedy = re.findall(r"<.*>", text)
non_greedy = re.findall(r"<.*?>", text)
print("Насыщенное:", greedy)
print("Ненасыщенное:", non_greedy)
Это покажет разницу между насыщенным и ненасыщенным совпадением.
Группировка с помощью скобок
Скобки позволяют группировать части regex:
import re
text = "John Smith ([email protected])"
result = re.search(r"(\w+) (\w+) \((\w+@\w+\.\w+)\)", text)
if result:
print(f"Полное имя: {result.group(1)} {result.group(2)}")
print(f"Электронная почта: {result.group(3)}")
Это извлекает имя и адрес электронной почты из текста.
Обратные ссылки
Обратные ссылки позволяют ссылаться на ранее совпадающие группы:
import re
text = "<h1>Title</h1><p>Paragraph</p>"
result = re.findall(r"<(\w+)>.*?</\1>", text)
print(result)
Это совпадает с открывающими и закрывающими тегами HTML.
Альтернативы
Символ | позволяет указывать альтернативы:
import re
text = "The color of the sky is blue or gray"
result = re.search(r"blue|gray", text)
if result:
print(f"Найден цвет: {result.group()}")
Это совпадает либо с "blue", либо с "gray".
Привязки
Привязки указывают позиции в тексте:
import re
text = "Python is awesome"
start = re.match(r"^Python", text)
end = re.search(r"awesome$", text)
print(f"Начинается с Python: {bool(start)}")
print(f"Заканчивается на awesome: {bool(end)}")
Это проверяет, начинается ли текст с "Python" и заканчивается ли на "awesome".
Специальная синтаксис с помощью скобок
Скобки могут использоваться не только для группировки:
- (?:...) создает некаптурирующую группу
- (?P
...) создает именованную группу - (?=...) создает положительное предварительное совпадение
- (?!...) создает отрицательное предварительное совпадение
import re
text = "Python version 3.9.5"
result = re.search(r"Python (?:version )?(?P<version>\d+\.\d+\.\d+)", text)
if result:
print(f"Версия: {result.group('version')}")
Это извлекает номер версии, будь то "version" присутствует в тексте или нет.
Итак, это было наше путешествие по миру Python regex, от основ к более сложным концепциям. Помните, как и любое мощное инструмент, regex требует практики для мастерства. Так что не расстраивайтесь, если в начале это кажется сложным. Продолжайте экспериментировать, и скоро вы сможете искать шаблоны как настоящий сыщик! Удачи в кодинге!
Credits: Image by storyset
