Регулярные выражения в Python

Источники:

Некоторые люди, сталкиваясь с проблемой, думают: «О, я воспользуюсь регулярными выражениями».
Теперь у них две проблемы.
Джэйми Завински

Регуля́рные выраже́ния (англ. regular expressions) — формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов. Регулярные выражения – мощное, гибкое и эффективное средство обработки текстов. Универсальные шаблоны регулярных выражений сами по себе напоминают миниатюрный язык программирования, предназначенный для описания и разбора текста. При дополнительной поддержке со стороны конкретной утилиты или языка программирования регулярные выражения способны вставлять, удалять, выделять и выполнять самые невероятные операции с текстовыми данными любого вида. Они бывают очень простыми, вроде команды поиска в текстовом редакторе, или очень сложными, как специализированные языки обработки текстов.

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

  • найти все последовательности символов «кот» в любом контексте, как то: «кот», «котлета», «терракотовый»;
  • найти отдельно стоящее слово «кот» и заменить его на «кошка»;
  • найти слово «кот», которому предшествует слово «персидский» или «чеширский»;
  • убрать из текста все предложения, в которых упоминается слово кот или кошка. Регулярные выражения позволяют задавать и гораздо более сложные шаблоны поиска или замены.

Результатом работы с регулярным выражением может быть:

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

Если регулярное выражение используется для замены текста, то результатом работы будет новая текстовая строка, представляющая из себя исходный текст, из которого удалены найденные подстроки (сопоставленные образцу), а вместо них подставлены строки замены (возможно, модифицированные запомненными при разборе группами символов из исходного текста). Частным случаем модификации текста является удаление всех вхождений найденного образца — для чего строка замены указывается пустой.

Устройство

Регулярное выражение состоит из двух типов символов. Специальные символы (вроде * в файловых шаблонах) называются метасимволами. Все остальные символы, т. е. обычный текст, называются литералами.

Регулярные выражения можно рассматривать как самостоятельный язык, в котором литералы выполняют функции слов, а метасимволы – функции грамматических элементов. Слова по определенным правилам объединяются с грамматическими элементами и создают конструкции, выражающие некоторую мысль. Скажем, для поиска строк, начинающихся с ‘From:’ или ‘Subject:’ можно воспользовался регулярным выражением ^(From|Subject):.

Большие регулярные выражения строятся из маленьких «кирпичей». Сами по себе эти «кирпичи» просты, но в сочетании друг с другом они образуют бесконечное множество комбинаций. Чтобы научиться правильно объединять их для достижения желаемой цели, вам потребуется некоторый опыт.

(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)

Регулярное выражение для поиска email'ов.

Метасимволы

Метасимвол, си́мвол-джо́кер (си́мвол подстано́вки) — символ, используемый для замены других символов или их последовательностей, приводя таким образом к символьным шаблонам.

Вот полный список метасимволов:

. ^ $ * + ? { [ ] \ | ( )

[] – класс символов

Первые метасимволы, что мы рассмотрим это [ и ]. Они используются для определения класса символов, являющегося набором символов, с которыми вы ищите совпадение. Символы могут быть перечислены по отдельности, или в виде некоторого диапазона символов, обозначенного первым и последним символом, разделенных знаком -. Например, [abc] будет соответствовать любому из символов a, b или c; это то же самое, что выражение [a-c], использующее диапазон для задания того же множества символов. Если вы хотите сопоставить только строчные буквы, РВ будет иметь вид [a-z].

Метасимволы не активны внутри классов. Например, [akm]</code>будетсоответствоватьлюбомуизсимволов<code>a</code>,<code>k</code>,<code>m</code>или<code>]</code> будет соответствовать любому из символов <code>a</code>, <code>k</code>, <code>m</code> или <code>. Знак $ это обычно метасимвол (как видно из списка символов выше), но внутри класса символов он лишается своей особой природы.

Отрицание

Для того, чтобы находить соответствие символам вне этого класса, в начале класса добавляется символ ^. Например, выражение [^5] соответствует любому символу, кроме 5.

/ — экранирование и управляющие последовательности

Пожалуй, наиболее важным является метасимвол обратной косой черты \. Как и в строковых литералах Python, за бэкслешем могут следовать различные символы, обозначающие разные специальные последовательности. Он также используется для экранирования метасимволов, чтобы их можно было использовать в шаблонах; например, если нужно найти соответствие [ или \, для того чтобы лишить их своей особой роли метасимволов, перед ним нужно поставить обратную косую черту: \[ или \\\\.

Некоторые из специальных последовательностей, начинающихся с \ представляют предопределенные наборы символов, часто бывающие полезными, такие как набор цифр, набор букв, или множества всего, что не является пробелами, символами табуляции и т. д. (whitespace). Следующие предопределенные последовательности являются их подмножеством.

  • \d – соответствует любой цифре; эквивалент класса [0-9].
  • \D – cоответствует любому нечисловому символу; эквивалент класса [^0-9].
  • \s – cоответствует любому символу whitespace; эквивалент [ \t\n\r\f\v].
  • \S – cоответствует любому не-whitespace символу; эквивалент [^ \t\n\r\f\v].
  • \w – cоответствует любой букве или цифре; эквивалент [a-zA-Z0-9_].
  • \W – наоборот; эквивалент [^a-zA-Z0-9_].

Эти последовательности могут быть включены в класс символов. Например, [\s,.] является характер класс, который будет соответствовать любому whitespace-символу или запятой или точке.

Позиция внутри строки

Вероятно, простейшими метасимволами являются ^ (крышка, циркумфлекс) и $ (доллар), представляющие соответственно начало и конец проверяемой строки. Например, регулярное выражение cat находит последовательность символов c a t в любом месте строки, но для выражения ^cat совпадение происходит лишь в том случае, если символы c a t находятся в начале строки – ^ фактически привязывает совпадение (остальной части регулярного выражения) к началу строки. Аналогично, выражение cat$ находит символы c a t только в том случае, если они находятся в конце строки – например, если строка завершается словом scat.

Квантификация (поиск последовательностей)

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

Группы

Круглые скобки используются для определения области действия и приоритета операций. Шаблон внутри группы обрабатывается как единое целое и может быть квантифицирован. Например, выражение (тр[ау]м-?)* найдёт последовательность вида трам-трам-трумтрам-трум-трамтрум.

Использование регулярных выражение в Python

В Python для работы с регулярными выражениями есть модуль re (также же ещё есть модуль regex, который не входит в стандартную библиотеку модулей и предоставляет дополнительный функционали). Для использования его нужно импортировать:

import re repr(re)
""
dir(re)
['A',
'ASCII',
'DEBUG',
'DOTALL',
'I',
'IGNORECASE',
'L',
'LOCALE',
'M',
'MULTILINE',
'RegexFlag',
'S',
'Scanner',
'T',
'TEMPLATE',
'U',
'UNICODE',
'VERBOSE',
'X',
'_MAXCACHE',
'__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'__version__',
'_alphanum_bytes',
'_alphanum_str',
'_cache',
'_compile',
'_compile_repl',
'_expand',
'_locale',
'_pattern_type',
'_pickle',
'_subx',
'compile',
'copyreg',
'enum',
'error',
'escape',
'findall',
'finditer',
'fullmatch',
'functools',
'match',
'purge',
'search',
'split',
'sre_compile',
'sre_parse',
'sub',
'subn',
'template']

Давайте посмотрим на методы, которые предоставляет библиотека re для этих задач. Вот наиболее часто используемые из них:

  • re.match()
  • re.search()
  • re.findall()
  • re.split()
  • re.sub()
  • re.compile()

re.match(pattern, string)

Этот метод ищет по заданному шаблону в начале строки.

result = re.match("abc", "мама мыла раму") print(result)
None
result = re.match("м\w+", "мама мыла раму") print(result.group(0))
мама

Также есть методы start() и end() для того, чтобы узнать начальную и конечную позицию найденной строки.

result.start(), result.end()
(0, 4)

re.search(pattern, string)

Метод search() ищет по всей строке, но возвращает только первое найденное совпадение.

result = re.search("мы\w+", "мама мыла раму") print(result.group(0))
мыла

re.findall(pattern, string)

Этот метод возвращает список всех найденных совпадений. У метода findall() нет ограничений на поиск в начале или конце строки.

result = re.findall("\d+", "какие-то ци4324фры в строке 12 345") print(result)
['4324', '12', '345']

re.split(pattern, string, [maxsplit=0])

Этот метод разделяет строку по заданному шаблону.

result = re.split("\s+|_+", "какие-то_ци4324фры___в_строке 12 345") print(result)
['какие-то', 'ци4324фры', 'в', 'строке', '12', '345']

Метод split() принимает также аргумент maxsplit со значением по умолчанию, равным 0. В данном случае он разделит строку столько раз, сколько возможно, но если указать этот аргумент, то разделение будет произведено не более указанного количества раз.

re.compile(pattern, repl, string)

Мы можем собрать регулярное выражение в отдельный объект, который может быть использован для поиска. Это также избавляет от переписывания одного и того же выражения.

pattern = re.compile("\s+|_+") result = pattern.split("какие-то_ци4324фры___в_строке 12 345") print(result)
['какие-то', 'ци4324фры', 'в', 'строке', '12', '345']

Самостоятельная

  1. Напишите регулярное выражение для токенизации по символам пробелов и пунктуации.
  2. Верните список доменов из строки, котора содержит список адресов электронной почты
emails = "abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz"

Комментарии