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

Оглавление

Введение в REGEX

REGEX - это модуль, используемый для сопоставления регулярных выражений в языке программирования Python. На самом деле, REGEX - это сокращение от регулярных выражений, которые обозначают шаблон символов, используемых в строке. Это понятие может применяться к простым словам, телефонным номерам, адресам электронной почты или любым другим шаблонам. Например, если вы ищете букву "f" в предложении "Во имя всего хорошего, закончите работу", цель состоит в том, чтобы найти вхождения символа "f" в предложении. Это самое базовое применение регулярных выражений: вы можете искать только буквенные символы в строках, смешанных с буквами, цифрами и специальными символами. С другой стороны, в строке с текстом "a2435?#@s560" вы можете искать только буквы в этой строке. Можно также искать в тексте телефонные номера (###-###-####). Формат телефонного номера представляет собой очень специфический набор цифр, дефисов и более чем одного символа, общий синтаксис которого мы обсудим далее.

Во-первых, следует быстро отметить, что regex обычно чувствителен к регистру: буква "a" и буква "A" будут считаться отдельными символами. Кроме того, при работе с числами вы никогда не будете иметь дело более чем с одной цифрой за раз, поскольку нет ни одного символа, который бы обозначал что-то большее, чем от 0 до 9. Давайте рассмотрим некоторые важные метасимволы, используемые для ввода шаблонов, которые нам нужно искать. Как и обычные строки, шаблоны всегда начинаются и заканчиваются двойными кавычками (""). Допустим, вы ищете вхождения буквы "e": вы можете написать именно "e". Если вы ищете фразу, часть слова или целое слово, например, "was", то вы можете написать именно "was". Эти два варианта применения регулярных выражений ничем не отличаются от ввода регулярной строки.

Использование символов для создания отступов

Теперь перейдем к чему-то особенному: мы можем использовать точку (.) для обозначения любого символа, кроме символа новой строки, который создает отступы. Допустим, искомый шаблон - "h.s": это означает, что между "h" и "s" может находиться любой символ - буква, цифра или специальный символ. Наконец, у нас есть два символа, которые указывают на конкретную позицию шаблона.

  • Каретка (^) ищет шаблон, с которого начинается строка или текст. Так, если у вас есть предложение "Это похоже на дерево" и вы ищете шаблон "^This", то оно будет успешно найдено, поскольку "This" находится в начале. Каретка должна быть первым символом шаблона.
  • На противоположном конце спектра находится знак доллара ($), который указывает, что шаблон должен находиться в конце. Так, если в предыдущем примере шаблон будет "tree$", вы получите успешное совпадение, поскольку слово "tree" завершает строку. Знак доллара всегда должен завершать шаблон.

Следующая пара мета-символов относится к количеству повторений regex в строке.

  • Звездочка (*) проверяет нулевое или более количество вхождений шаблона. Это означает, что независимо от того, встречается ли конкретный символ, символы или шаблон на самом деле или нет, он всегда будет совпадать. Например, если у нас есть шаблон "abc*", то до тех пор, пока у нас есть строка, содержащая "ab", она пройдет. Буква "c" может встречаться или нет, она будет соответствовать требованиям. Таким образом, строки "ab", "abc" и "abccc" соответствуют шаблону.
  • Знак плюс (+) проверяет наличие одного или более вхождений шаблона. Это означает, что если шаблон встречается хотя бы один раз, то совпадение было успешным. Отсутствие вхождений означает, что совпадение было неудачным. Вы также можете использовать скобки () и вводить между ними определенное количество вхождений, которое вы ищете. Все эти метасимволы следуют за регексом.
  • Вертикальная полоса (|), как и в языках программирования, обозначает "или". Если бы у вас было предложение "Я вылетаю из Майами в шесть часов", а регекс был бы "go|departing", совпадение было бы успешным, потому что, хотя "go" отсутствует, "departing" присутствует.

Наборы в REGEX

Далее мы рассмотрим наборы, создаваемые скобками ([]). Набор расширяет возможности создания шаблонов и представляет собой ровно 1 символ. Например, если у вас есть шаблон "abc", то это означает, что вы буквально ищете "abc". Однако если шаблон имеет вид "[abc]", то вы ищете вхождения "a", "b" или "c". Аналогично, "0123" означает, что вы буквально ищете "0123". Если у вас есть "[0123]", то вы ищете вхождения 0, 1, 2 или 3.

Дефис (-) между двумя буквами или символами означает, что любое появление символа между ними является совпадением. Таким образом, "[0-9]" относится ко всем цифровым цифрам, а "[a-zA-Z]" - ко всем алфавитным символам, как в нижнем, так и в верхнем регистре. Вы также можете ограничить количество символов: например, "[4-7]" или "[p-v]" также вполне приемлемы.

Функция каретки (^) меняется в пределах набора. Каретка ищет все, кроме введенного вами шаблона. Так, если у вас есть [^abc], вы хотите найти любой символ, кроме "a", "b" или "c". Кроме каретки, метасимволы в наборах не имеют специальных функций. Это означает, что "[+]" буквально ищет вхождения символа "+" и больше не считается метасимволом. Если вы хотите применить мета-символы к наборам, вы используете их вне набора, например, "[0-9]*" или "[G-N]$". Комбинируя наборы, например, "[v-z][a-g]", можно создать множество различных шаблонов. Так можно найти числа с несколькими цифрами. Для поиска двузначного числа можно использовать "[0-9][0-9]".

Специальные последовательности с использованием обратной косой черты

В заключение мы кратко обсудим специальные последовательности. Во-первых, специальные последовательности инициируются другим мета-символом, который ранее не обсуждался, - обратной косой чертой (\) и определенной буквой в зависимости от последовательности. Специальные последовательности работают очень похоже на другие мета-символы в том смысле, что они выполняют специальные функции, как и мета-символы. Более того, некоторые из них выполняют те же функции, что и некоторые мета-символы. Последовательности "\A", "\b" и "\B" обозначают определенное положение символов, так же как каретка и знак доллара.

Последовательность "\A" проверяет, совпадает ли шаблон с началом строки. Например, если у нас есть шаблон "\AThe" и у нас есть строка "The Tree", то шаблон совпадает. Однако, если бы у нас была строка "Find The Tree", то совпадения не было бы, потому что "the" не инициирует строку.

Последовательность "\b" указывает, что шаблон либо начинает, либо заканчивает слово в строке.

  • Если вы хотите узнать, начинается ли слово с "eb", шаблон будет выглядеть как "\beb".
  • Если вы хотите узнать, начинается ли слово с "eb", шаблон будет выглядеть как "eb\b".
  • Если у нас есть слово "celeb", оно не будет соответствовать шаблону "\beb", так как не начинается с "eb".

Слово "celeb" будет соответствовать шаблону "eb\b", так как слово заканчивается на "eb". Последовательность "\B" реализуется так же, как и "\b", но имеет прямо противоположное значение. Последовательность "\B" совпадает до тех пор, пока слово не начинается или заканчивается шаблоном. Давайте снова рассмотрим предыдущий пример. Если у нас есть слово "знаменитость" и шаблон "\Beb", то шаблон совпадает, так как "eb" не начинается со слова. Если у нас есть образец "eb\B", то слово не будет соответствовать образцу, так как "eb" заканчивает слово.

Многие другие последовательности предназначены для выделения определенных типов символов. Например, "\d" возвращает совпадение для любого символа, который является цифрой, а "\D" возвращает совпадение для всего, что не является цифрой. По этой причине специальные последовательности используются для очень широкого применения. Если вы просто хотите найти все цифры, буквы или что-то еще столь же широкое, специальные последовательности более удобны. В противном случае рекомендуется использовать другие метасимволы.

Программирование на языке Python с использованием REGEX

Теперь мы можем поговорить о модуле, который позволяет языку программирования Python использовать REGEX, "re". Модуль "re" встроен в Python, поэтому его установка не требуется, если он у вас уже установлен. Для того чтобы использовать модуль, достаточно импортировать его.

import re

Сначала поговорим о функции компиляции. Используя "re.compile", мы можем превратить REGEX в объект для последующего использования. Вы можете просто ввести шаблон в другие функции, но создание объекта более удобно.

import re
pattern = "[abcABC]+"
regex = re.compile(pattern)

Следующей является функция поиска. Она возвращает объект match после нахождения первого экземпляра regex в строке. Например:

import re
pattern = "[abcABC]+"
regex = re.compile(pattern)
string1 = "Jaime lives in Florida."
Results = regex.search(string1)
print(Results)
#Results = <_sre.SRE_Match object; span=(1, 2), match='a'>

Если вхождение не найдено, то возвращается только "None".

import re
pattern = "[abcABC]+"
regex = re.compile(pattern)
string2 = "Ron lives in New Jersey"
Results = regex.search(string2)
print(Results)
#Results = None

Теперь рассмотрим функцию match. Функция проверяет, совпадает ли начало строки с REGEX. Если да, то возвращается объект match и "None" в противном случае. Обратите внимание, что проще всего, чтобы функция не сработала, так как есть дополнительное ограничение.

import re
pattern = "[abcABC]+"
regex = re.compile(pattern)
string3 = "Luis never makes excuses."
Results = regex.match(string3)
print(Results)
#Results = None
string4 = "Archer never makes excuses."
Results = regex.match(string4)
print(Results)
#Results = <_sre.SRE_Match object; span=(0, 1), match='A'>

Наконец, есть функция "fullmatch". В отличие от re.match, re.fullmatch будет проверять, точно ли вся строка соответствует шаблону. Например:

import re
pattern = "[abcABC]+"
regex = re.compile(pattern)
string5 = "Another one bites the dust"
Results = regex.fullmatch(string5)
print(Results)
#Results = None
string6="ABCABabbcaa"
Results = regex.fullmatch(string6)
print(Results)
#Results = <_sre.SRE_Match object; span=(0, 11), match='ABCABabbcaa'>

Выбирая между re.match и re.search

Следует отметить, что, как и в большинстве модулей, связанных со строками, функции могут ограничивать область поиска, вводя первый и последний индексы нужного участка строки. Это ставит вопрос о том, что лучше использовать - re.match или re.search, поскольку они имеют схожие цели.

Основная проблема re.match и re.fullmatch заключается в том, что они оба очень ограничены в том, какие части строк вы ищете. Допустим, у вас есть все содержимое книги в текстовом файле, и я хочу проверить весь документ на наличие определенного, редкого шаблона в виде одного слова или фразы. Единственный реальный способ продуктивного поиска с помощью re.fullmatch - это разбить весь документ на очень большой список из множества слов и проверить каждое слово по отдельности. Это может занять много времени и памяти. Итак, как бы мы применили re.match к этой проблеме?

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

Рассмотрим случай, когда нам нужно только подтвердить, что начало строки соответствует regex. Это довольно просто, если мы используем re.match, но если мы используем re.search, он также может вернуть true, где true. Проблема с re.search, однако, заключается в том, что re.search будет искать любое вхождение в строке. Поэтому re.search может вернуть true там, где он не должен. В этом случае мы можем изменить regex и добавить каретку (^), чтобы исправить ситуацию. Однако в этом случае проще использовать re.match.

Заключительные мысли

В конечном итоге, Regex как инструмент является универсальным средством для анализа любой формы текста. Вы можете сканировать документы любого формата и любого объема информации, чтобы извлечь конкретную информацию с помощью Regex. Вы можете просмотреть книгу, чтобы найти все вхождения слова, вплоть до сканирования онлайн-каталога, чтобы найти контактную информацию определенных компаний. Автоматизация этих трудоемких задач необходима в нашем современном мире, и, прочитав эту статью, вы сделали первые шаги к освоению этого инструмента.

Вернуться на верх