Регулярные выражения (часто обозначаются как "regex" или "regexp") представляют собой мощный инструмент в арсенале программиста, позволяющий управлять проверкой, поиском и заменой строк на основе описательных шаблонов.
Регулярные выражения так же применяются для проверки формата данных, например, телефонного номера, email и др.
Работа регулярных выражений имеет высокую скорость выполнения сложных процессов по поиску и замене подстрок. В этой статье мы изучим, как использовать регулярные выражения в Python, а также рассмотрим примеры применения для решения реальных задач.
Инструментарий регулярных выражений
Перед погружением в примеры и задачи давайте разберём ключевые конструкции и шаблоны регулярных выражений:
- . # Соответствует любому символу, кроме новой строки \n.
- ? # Указывает, что предшествующий символ или группа может присутствовать 0 или 1 раз.
- + # Значит, что предыдущий элемент должен появиться один или несколько раз.
- * # Обозначает, что предыдущий элемент может встретиться 0 и более раз.
- \w # Соответствует любой букве, цифре или символу подчёркивания (используется для слов), противоположность \W, где \W — все, кроме буквы или цифры.
- \d # Указывает на любую цифру от 0 до 9, противоположность \D, где \D обозначает всё, кроме цифры.
- \s # Соответствует любому пробельному символу (включая пробелы, табуляции и новые строки), противоположность \S, где \S — любой непробельный символ.
- \b # Граница слова — позиция, где символы с правой стороны либо слова, либо пустые, а слева — не слово.
- [abc] # Соответствует любому из символов в скобках. [a-z] — диапазон от 'a' до 'z'.
- [..] # Один из символов в скобках ([^..] — любой символ, кроме тех, что в скобках).
- ^ и $ # Начало и конец строки соответственно.
- {n,m} # Указывает количество повторений предыдущего элемента от n до m раз. От n до m вхождений ({,m} — от 0 до m).
- a|b # Соответствует либо a, либо b.
- () # Группировка элементов для упрощения сложных выражений и извлечения соответствий. Группирует выражение и возвращает найденный текст.
- \t, \n, \r # Символ табуляции, новой строки и возврата каретки соответственно.
Примеры задач
Задача 1: Проверка формата электронной почты
Рассмотрим шаблон регулярного выражения для проверки корректности формата электронной почты:
Тот же код ниже для копирования и вставки в программу. Не забывайте про необходимый отступ пробелами в определённых местах в начале строки, так как код на сервере блога может отображаться некорректно.
import re
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
email = "example@domain.com"
match = re.fullmatch(pattern, email)
if match:
print("Корректный адрес электронной почты.")
else:
print("Некорректный адрес электронной почты.")
Разбор кода:
- ^[a-zA-Z0-9._%+-]+: Начало строки, за которой следует один или более символов (буквы, цифры, и некоторые специальные символы).
- @[a-zA-Z0-9.-]+: Обязывает присутствовать символ @ и доменное имя (обычно между a-z, A-Z, 0-9, . и -).
- \.[a-zA-Z]{2,}$: Точка перед доменной зоной и минимум двумя буквенными символами.
Рекомендация: Добавьте дополнительные проверки, позволяющие поддерживать ещё больше доменных зон (например, кириллические домены).
Задача 2: Поиск всех хеш-тегов в сообщении
Предположим, перед нами стоит задача извлечь все хеш-теги из текста:
Тот же код ниже для копирования и вставки в программу. Не забывайте про необходимый отступ пробелами в определённых местах в начале строки, так как код на сервере блога может отображаться некорректно.
import re
text = "Люблю #python и #разработка #dev"
hashtags = re.findall(r'#\w+', text)
print("Найденные хеш-теги:", hashtags)
Разбор кода:
- #: Начинается с символа решётки, что сигнализирует о начале хеш-тега.
- \w+: Обозначает одно или более вхождений буквы, цифры или подчёркивания после символа #.
Рекомендация: Подумайте о возможности поиска и неанглоязычных хеш-тегов, добавив поддержку Unicode-символов.
Группы и ленивые квантификаторы
Квантификаторы — это мощные инструменты в регулярных выражениях, которые позволяют задавать количество повторений предшествующего элемента. Благодаря ним, регулярные выражения становятся более гибкими и позволяют более точно описывать требования к соответствующим строкам. Рассмотрим подробнее каждый из распространенных квантификаторов:
- {n} — Ровно n повторений. Этот квантификатор указывает, что предшествующий ему элемент должен повторяться ровно n раз. Пример выражения: \d{4}. Применение: Будет соответствовать строкам с четырьмя подряд идущими цифрами. Например, в строке "1234", "5678".
- {m,n} — От m до n повторений включительно. Указывает, что предшествующий элемент должен повторяться от m до n раз. Пример выражения: \d{2,4}. Применение: Соответствует строкам, содержащим от двух до четырех цифр подряд. Например, "12", "345", "6789".
- {m,} — Не менее m повторений. Этот квантификатор требует, чтобы элемент повторялся не меньше m раз. Пример выражения: \d{3,}. Применение: Соответствует строкам, содержащим не менее трех цифр подряд. Например, "123", "4567".
- {,n} — Не более n повторений. Указывает на повторение не более n раз. Пример выражения: \d{,2}. Применение: Соответствует строкам с максимум двумя подряд идущими цифрами. Например, "1", "23".
- ? — Ноль или одно вхождение (синоним {0,1}). Позволяет элементу появляться один раз или пропустить его. Пример выражения: валы?Применение: Соответствует строкам "вал" или "валы", т.к. символ 'ы' может встречаться либо один раз, либо отсутствовать.
- * — Ноль или более (синоним {0,}). Разрешает элементу появляться любое количество раз, в том числе и отсутствовать. Пример выражения: СУ\d*. Применение: Соответствует строкам "СУ", "СУ1", "СУ12", т.к. после "СУ" может следовать любое количество цифр, включая ноль.
- + — Одно или более (синоним {1,}). Требует, чтобы элемент присутствовал как минимум один раз. Пример выражения: a\)+. Применение: Соответствует строкам вроде "a)" или "a))" и т.д. После символа 'a' должно присутствовать по крайней мере одна закрывающая скобка.
Квантификаторы предоставляют гибкость и мощь регулярных выражений, позволяя настраивать количество вхождений и получать более точные результаты при обработке текстов. Они полезны в решении задач разнообразной сложности, от простых до регулярного ввода и валидации данных.
Группы в регулярном выражении
Группы позволяют связывать части выражений и выполнять действия на них. Например, рассмотрим выделение внутренностей скобок в строке:
Разбор кода:
- \((.*?)\): Совпадение с символами внутри скобок.
- .*?: Между скобками любой символ (.), повторяющийся 0 и более раз, с ленивой минимизацией (*?), чтобы захват не был жадным.
Рекомендация: Используя группы, подобный подход можно расширить для поиска с учётом вложенных скобок.
Группы в регулярных выражениях служат нескольким важным целям, которые делают их мощным инструментом для управления текстом. Давайте разберём, как группы могут оптимизировать шаблоны и упростить извлечение данных.
Применение групп для сокращения повторяющихся частей
Рассмотрим пример с форматом MAC-адреса, который обычно представлен как шесть групп по две шестнадцатеричные цифры, разделённых символами : или -. Такой адрес может выглядеть следующим образом: 01:23:45:67:89:ab.
Без группировки, шаблон регулярного выражения будет достаточно громоздким.
С применением групп, мы можем сократить дробление:
([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}
Разъяснение:
- [0-9a-fA-F]{2} # Соответствует двум шестнадцатеричным символам.
- [:-] # Соответствует либо двоеточию, либо дефису.
- (...){5}: # Группа из двух шестнадцатеричных символов и разделителя повторяется пять раз.
- [0-9a-fA-F]{2}: # Последняя пара шестнадцатеричных символов (без разделителя).
Группы помогают не только упростить чтение шаблона, но и предлагают возможность задавать диапазон повторений (например, {1,5} для от 1 до 5 повторений).
Извлечение информации с помощью групп
Группы позволяют извлекать содержимое каждой части, заключённой в скобки, отдельно. Это важно при анализе строк, где нужно получить конкретные части данных.
Например:
Разъяснение:
- ([А-Яа-яЁё]+): первая группа, соответствующая строке из одной или более кириллицы.
- (\d+): вторая группа, соответствующая одной или более цифрам.
Результаты:
- match.group() или match[0]: возвращает полное совпадение — "Опять 45".
- match.group(1) или match[1]: возвращает содержимое первой группы — "Опять".
- match.group(2) или match[2]: возвращает содержимое второй группы — "45".
Давайте подробнее рассмотрим два важных аспекта использования групп в регулярных выражениях: возможность задавать диапазон повторений и извлечение матчей по группам с помощью объектов совпадения.
1. Задание диапазона повторений в группах
Одной из отличительных черт использования групп является возможность задавать не только точное количество повторений, но и диапазон. Это особенно полезно, когда количество повторений изменяется или неизвестно заранее.
Пример:
Предположим, вы работаете с форматом, в котором одна и та же структура повторяется variable количество раз. В данном случае, мы рассматриваем одинаковые группы из цифр, разделённые пробелами.
Разъяснение:
- (\d{2} )+: соответствует одной или более парам двух цифр, каждая из которых заканчивается пробелом. Поскольку используется +, совпадение ожидается от одного до бесконечно большого количества.
2. Извлечение данных с помощью групп и match-объектов
Регулярные выражения в Python предоставляют удобные средства для извлечения матчей отдельных групп посредством объектов совпадения. Используя функции, такие как re.search(), re.fullmatch() и re.finditer(), группы могут быть адресованы отдельно в возвращённых match-объектах. Это позволяет получить доступ не только к самим совпадениям, но и к их индексам в исходной строке.
Пример:
Тот же код ниже для копирования и вставки в программу. Не забывайте про необходимый отступ пробелами в определённых местах в начале строки, так как код на сервере блога может отображаться некорректно.
import re
text = "Дата начала: 2023-10-15, Дата конца: 2023-11-01"
pattern = r"(\d{4})-(\d{2})-(\d{2})"
matches = re.finditer(pattern, text)
for match in matches:
print("Полное совпадение:", match.group())
print("Год:", match.group(1))
print("Месяц:", match.group(2))
print("День:", match.group(3))
print("Индексы:", match.span())
Разъяснение:
- (\d{4}): первая группа, извлекающая год.
- (\d{2}): вторая и третья группы для месяца и дня.
- match.group(): возвращает полное совпадение.
- match.group(n): возвращает n-ую группу.
- match.span(): возвращает начальный и конечный индексы полного совпадения в оригинальной строке.
Результат работы кода:
Использование групп в регулярных выражениях предоставляет значительное преимущество при работе с текстами. Возможность задавать диапазоны повторений делает шаблоны гибкими, а доступ к матчам через объекты позволяет извлекать именно те данные, которые вам необходимы. Эти инструменты делают регулярные выражения мощным средством текстовой обработки различной сложности.
Использование групп в регулярных выражениях позволяет делать более сложные и выразительные шаблоны, которые проще читать, поддерживать и развивать. Они играют ключевую роль в защите от избыточности и предоставляют удобство при выделении интересующих фрагментов текста. Группы можно комбинировать с другими аспектами регулярных выражений, например, с жадными и ленивыми квантификаторами, чтобы разрабатывать мощные текстовые фильтры и анализаторы.
Заключение
Регулярные выражения — это чрезвычайно эффективный инструмент для обработки текста, которым, овладев однажды, позволит вам решать многие задачи для работы со строками элегантно и эффективно. Понимание символов и конструкций делает их использование интуитивно понятным и мощным. Используйте регулярные выражения вдумчиво и совершенствуйте ваши навыки!
Для лучшего понимания и практики работы с регулярными выражениями в Python, рекомендую обратиться к более комплексным примерам и дополнительным источникам, такими как документация Python и тематические обучающие ресурсы, такие как профильные статьи и форумы.
Полезные ресурсы:
---------------------------------------
Сообщество дизайнеров в VK
https://vk.com/grafantonkozlov
Телеграмм канал сообщества
https://t.me/grafantonkozlov
Архив эксклюзивного контента
https://boosty.to/antonkzv
Канал на Дзен
https://dzen.ru/grafantonkozlov
---------------------------------------
Бесплатный Хостинг и доменное имя
https://tilda.cc/?r=4159746
Мощная и надежная нейронная сеть Gerwin AI
https://t.me/GerwinPromoBot?start=referrer_3CKSERJX
GPTs — плагины и ассистенты для ChatGPT на русском языке
https://gptunnel.ru/?ref=Anton
---------------------------------------
Донат для автора блога