Регулярные выражения и модуль re в Python

Регулярные выражения — это мощный инструмент для работы с текстом, особенно когда нужно искать, изменять или извлекать информацию из строк. В Python для работы с регулярками используется встроенный модуль re.


Основы регулярных выражений

Начнём с самых простых конструкций и перейдём к более сложным. Каждое регулярное выражение состоит из символов, каждый из которых имеет своё назначение.

Базовый синтаксис:

СимволЗначение
.Любой символ (кроме новой строки).
\dЛюбая цифра (эквивалентно [0-9]).
\DЛюбой символ, кроме цифры.
\wЛюбая цифра, буква или символ подчеркивания (эквивалентно [a-zA-Z0-9_]).
\WЛюбой символ, кроме буквы, цифры или подчеркивания.
\sЛюбой пробельный символ (включая пробел, табуляцию).
\SЛюбой символ, кроме пробела.
^Начало строки.
$Конец строки.
*0 или больше повторений.
+1 или больше повторений.
?0 или 1 повторение.
[]Символьный класс, определяющий множество допустимых символов.
()Группировка символов (создание подмаски).
``

Основные методы модуля re

Перед тем как углубляться в примеры, рассмотрим ключевые методы модуля re:

  • re.match() — ищет совпадение с регулярным выражением в начале строки.
  • re.search() — ищет первое совпадение по всему тексту.
  • re.findall() — возвращает все совпадения в виде списка.
  • re.sub() — заменяет все совпадения по шаблону.
  • re.split() — разделяет строку по шаблону.
  • re.compile() — компилирует регулярное выражение для повторного использования.

Примеры с подробными объяснениями


Пример 1: Поиск цифр в строке с помощью re.search()

Давай рассмотрим пример поиска первой последовательности цифр в строке.

import re

pattern = r'\d+'  # Ищем одну или более цифр
text = "Сегодня 15 градусов тепла, а завтра 20."

match = re.search(pattern, text)

if match:
    print(f"Найдено: {match.group()}")  # Результат: 15

Подробное объяснение:

  • r'\d+': регулярное выражение начинается с \d, что означает цифра (это соответствует любой цифре от 0 до 9). + означает одна или более цифр.
    • Символ r перед строкой говорит Python трактовать строку как "сырую" (raw string), что позволяет нам использовать обратный слеш без удвоения (\\).
  • re.search(pattern, text): функция search ищет первую подходящую последовательность в строке.
  • match.group(): если совпадение найдено, метод group() возвращает текст совпадения.


Пример 2: Проверка правильности email

Теперь более сложный пример — валидация email-адресов.

import re

pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
email = "test.email@example.com"

if re.match(pattern, email):
    print("Валидный email")
else:
    print("Невалидный email")

Подробное объяснение:

  • ^: начало строки.
  • [a-zA-Z0-9_.+-]+: любой набор букв, цифр, символов подчеркивания (_), точки (.), плюса (+), дефиса (-). Символ + означает "один или более символов".
  • @: символ "собака", который обязательно должен присутствовать в email.
  • [a-zA-Z0-9-]+: доменное имя, состоящее из букв, цифр или дефиса.
  • \.: символ точки. Поскольку точка — это специальный символ, её нужно экранировать с помощью \.
  • [a-zA-Z0-9-.]+: доменное расширение, содержащее буквы, цифры, точку или дефис.
  • $: конец строки.

Таким образом, это регулярное выражение проверяет наличие всех обязательных компонентов email: имя пользователя, символ @, доменное имя и доменное расширение.


Пример 3: Вытаскивание всех номеров телефонов из текста

Допустим, у нас есть текст, и нам нужно вытащить все номера телефонов, представленные в формате "+7-XXX-XXX-XX-XX".

import re

text = "Мои номера: +7-123-456-78-90, +7-987-654-32-10."
pattern = r'\+7-\d{3}-\d{3}-\d{2}-\d{2}'

phones = re.findall(pattern, text)
print(phones)  # Результат: ['+7-123-456-78-90', '+7-987-654-32-10']

Подробное объяснение:

  • \+7: символ + экранируется, так как он является специальным символом в регулярках. Здесь ищется точное совпадение с "+7".
  • \d{3}: три цифры подряд. {3} указывает на точное количество повторений цифр.
  • -: символ дефиса, который разделяет части номера.
  • Остальная часть повторяет этот же принцип для остальных сегментов номера (три цифры, затем две цифры и ещё две).


Пример 4: Разделение строки с помощью re.split()

Регулярные выражения могут использоваться для разделения строки по любому шаблону. Например, разделим строку по любому количеству пробелов, включая табуляцию.

import re

text = "apple     banana   orange\tgrape"
pattern = r'\s+'  # Одна или более пробельных символов

words = re.split(pattern, text)
print(words)  # Результат: ['apple', 'banana', 'orange', 'grape']

Подробное объяснение:

  • \s+: символ \s означает любой пробельный символ (включая пробелы, табуляции, переносы строк). Символ + означает "один или более пробелов".
  • re.split(pattern, text): этот метод разбивает строку по каждому совпадению шаблона.


Пример 5: Замена текста с помощью re.sub()

Регулярные выражения позволяют заменять текст. Например, заменим все цифры в строке на слово "NUM".

import re

text = "У меня 2 яблока и 3 банана."
pattern = r'\d+'  # Одна или более цифр

new_text = re.sub(pattern, 'NUM', text)
print(new_text)  # Результат: "У меня NUM яблока и NUM банана."

Подробное объяснение:

  • \d+: ищем одну или более цифр в строке.
  • re.sub(pattern, replacement, text): заменяет все вхождения, соответствующие pattern, на строку replacement (в нашем случае "NUM").


Пример 6: Поиск по группе с использованием подмасок

Регулярные выражения позволяют группировать части шаблонов с помощью скобок (). Это полезно, когда нужно извлечь часть совпадения. Рассмотрим пример с поиском даты в формате "день/месяц/год".

import re

text = "Дата: 12/08/2024."
pattern = r'(\d{2})/(\d{2})/(\d{4})'

match = re.search(pattern, text)
if match:
    day, month, year = match.groups()
    print(f"День: {day}, Месяц: {month}, Год: {year}")

Подробное объяснение:

  • (\d{2}): группа для двух цифр, представляющих день.
  • (\d{2}): группа для двух цифр, представляющих месяц.
  • (\d{4}): группа для четырёх цифр, представляющих год.
  • match.groups(): возвращает кортеж, содержащий все группы.

Пример вывода:

День: 12, Месяц: 08, Год: 2024

Этот пример показывает, как с помощью группировки можно извлечь отдельные части совпадения и использовать их по отдельности.


Дополнительные сложные примеры


Пример 7: Проверка валидности IP-адреса

IP-адрес состоит из четырёх чисел от 0 до 255, разделённых точками.

import re

text = "192.168.0.1 256.100.50.25 10.0.0.256"
pattern = r'^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.' \
          r'(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.' \
          r'(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.' \
          r'(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$'

ips = re.findall(pattern, text)
print(ips)  # Результат: ['192.168.0.1']

Подробное объяснение:

  • 25[0-5]: числа от 250 до 255.
  • 2[0-4][0-9]: числа от 200 до 249.
  • [0-1]?[0-9][0-9]?: числа от 0 до 199, включая числа с одной или двумя цифрами.
  • \.: точка разделяет сегменты IP. Поскольку точка — специальный символ, её нужно экранировать.
  • ^ и $: начало и конец строки для проверки полного совпадения.

Пример 8: Извлечение всех ссылок из HTML-текста

В этом примере мы извлечём все ссылки из HTML-кода.

import re

html_text = '''
    <a href="https://example.com">Example</a>
    <a href="https://google.com">Google</a>
'''

pattern = r'href="(https?://[^\"]+)"'

links = re.findall(pattern, html_text)
print(links)  # Результат: ['https://example.com', 'https://google.com']

Подробное объяснение:

  • href=": начало ссылки.
  • https?://: протокол (может быть http или https).
  • [^\"]+: любой символ, кроме кавычек, для захвата URL.
  • ": конец ссылки.


Пример 9: Извлечение всех дат в формате "день.месяц.год"

Извлечём все даты из строки, где даты представлены в формате "день.месяц.год".

import re

text = "События произошли 01.12.2024 и 23.06.2023."
pattern = r'(\d{2})\.(\d{2})\.(\d{4})'

dates = re.findall(pattern, text)
print(dates)  # Результат: [('01', '12', '2024'), ('23', '06', '2023')]

Подробное объяснение:

  • (\d{2})\.: группа для двух цифр, представляющих день, за которой следует точка.
  • (\d{2})\.: группа для двух цифр, представляющих месяц, за которой следует точка.
  • (\d{4}): группа для четырёх цифр, представляющих год.
  • re.findall(pattern, text): возвращает список кортежей, где каждый кортеж содержит группы.

Регулярные выражения — мощный инструмент для работы с текстом в Python. Они позволяют искать, извлекать, заменять и разделять строки на основе шаблонов. Овладение регулярными выражениями может значительно улучшить эффективность обработки текста и данных.

Если у тебя возникнут вопросы или ты хочешь изучить дополнительные примеры, не стесняйся обращаться!

Перейти к следующему шагу

Комментарии