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

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

Что такое регулярные выражения?

Регулярные выражения – необходимый компонент почти любого языка программирования. Чтобы работать с ними в Python, используется модуль re.

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

Отдельно следует сказать пару слов о шаблонах регулярных выражений. Это специальный язык, с помощью которого разработчик может извлекать цифры и символы, текст и другие значения, которые подпадают под этот шаблон. Например, с помощью шаблона \s+  мы задаем символ, который имеет хотя бы один пробел.

Разложим его на составляющие. С косой черты начинается запись любого регулярного выражения. Далее следует символ, который означает ту или иную его возможность. В нашем случае это – строка. После того, как мы добавили оператор + в конец, то задаем правило – минимум 1 символ.

То есть, описанный выше шаблон может использоваться и для символов tab (если регулярные выражения использовать, то это соответствует символу \t). Чтобы использовать регулярные выражения в Python, необходимо сначала импортировать библиотеку re, а потом использовать специальную функцию для компиляции. 

Разбиение строки, разделенной регулярным выражением

А теперь давайте проанализируем следующий фрагмент. 

>>> text = """100 ИНФ  Информатика

213 МАТ  Математика  

156 АНГ  Английский"""

Здесь содержится информация о трех курсах, записанных в формате «“[Номер курса] [Код курса] [Название курса]». Между словами интервал разный.

Итак, предположим, надо выполнить разбиение этих предметов на числа, слова отдельно. 

Как это сделать? Есть два способа.

  1. Использовать метод re.split
  2. Использовать метод split для объекта regex.
# Разделить текст по 1 или более пробелами  

>>> re.split('\s+', text)  

# или

>>> regex.split(text)  

['100', 'ИНФ', 'Информатика', '213', 'МАТ', 'Математика', '156', 'АНГ', 'Английский']

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

Использование функций findall(), search(), match() для поиска совпадений в тексте

Предположим, нужно извлечь номера из примера выше. Что делается для этого?

Какие действия выполняет re.findall()?

Для начала давайте приведем пример. 

#найти все номера в тексте

>>> print(text)  

100 ИНФ  Информатика

213 МАТ  Математика  

156 АНГ  Английский

>>> regex_num = re.compile('\d+')  

>>> regex_num.findall(text)  

['100', '213', '156']

Здесь есть специальный символ \d, являющий собой регулярное выражение. Оно обозначает любую цифру, которая есть в строке. 

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

С помощью метода findall() мы можем получить все вхождения 1 или более номеров из текста и вернуть их в форме списка.

Использование функции re.search и re.match

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

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

>>> # создайте переменную с текстом

>>> text2 = """ИНФ  Информатика

213 МАТ  Математика 156"""  

>>> # скомпилируйте regex и найдите шаблоны

>>> regex_num = re.compile('\d+')  

>>> s = regex_num.search(text2)  

>>> print('Первый индекс: ', s.start())  

>>> print('Последний индекс: ', s.end())  

>>> print(text2[s.start():s.end()]) 

Первый индекс:  17 

Последний индекс:  20

213

Есть и альтернативный вариант. Получение того же результата возможно с помощью функции group, которая применяется к искомому объекту. 

>>> print(s.group())  

205

>>> m = regex_num.match(text2)  

>>> print(m)  

None

Использование регулярных выражений для замены текста

Чтобы изменить текст, необходимо применять метод sub(). Давайте попробуем изменить немного описанный выше пример. Точно так же будем использовать названия курсов, только между кодовым и числовым обозначениями курсов и непосредственно названием будет использоваться пробел. 

# создайте переменную с текстом

>>> text = """100 ИНФ \t Информатика

213 МАТ \t Математика  

156 АНГ \t Английский"""  

>>> print(text)

  

100 ИНФ Информатика

213 МАТ Математика  

156 АНГ Английский

Из текста, который указан выше, необходимо удалить все ненужные пробелы и все слова записать в виде одной строки. 

Для этого достаточно использовать regex.sub. Если использовать эту функцию, то каждое вхождение, соответствующее шаблону \s+, заменяется на один пробел. 

# заменить один или больше пробелов на 1

>>> regex = re.compile('\s+')  

>>> print(regex.sub(' ', text))

Или так. 

>>> print(re.sub('\s+', ' ', text))  


101 COM Computers 205 MAT Mathematics 189 ENG English

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

Для того, чтобы выполнить эту задачу, используется отрицательное соответствие. С помощью шаблона (?!\n) программа будет проверять, есть ли символ новой строки. Если да, то он будет просто пропускаться. 

# убрать все пробелы кроме символа новой строки  

>>> regex = re.compile('((?!\n)\s+)')  

>>> print(regex.sub(' ', text))  

100 ИНФ Информатика

213 МАТ Математика  

156 АНГ Английский

Понятие групп регулярных выражений

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

Допустим, необходимо получить номер курса, код и имя в такой форме. Если не использовать группы регулярных выражений, то это делается приблизительно так. 

>>> text = """100  ИНФ  Информатика

213  МАТ  Математика  

156  АНГ  Английский"""  

# извлечь все номера курсов  

>>> re.findall('[0-9]+', text)  

# извлечь все коды курсов (для латиницы [A-Z])

>>> re.findall('[А-ЯЁ]{3}', text)  

# извлечь все названия курсов

>>> re.findall('[а-яА-ЯёЁ]{4,}', text)  

['100', '213', '156']  

['ИНФ', 'МАТ', 'АНГ']  

['Информатика', 'Математика', 'Английский']

А теперь давайте проанализируем получившийся результат. Здесь были скомпилированы 3 регулярных выражения. Каждое из них соответствует номеру курса, буквенному коду и названию. 

Для номер курса мы использовали шаблон [0-9]+, с помощью которого задается соответствие любому числу в диапазоне от 0 до 9. За счет добавления знака + в конце, программа ищет хотя бы одно соответствие этим значениям. Если вы имеете уверенность в том, что номер курса имеет ровно 3 цифры, шаблон может быть следующим [0-9] {3}.

В случае с кодом курса регулярное выражение ищет совпадение с тремя большими буквами алфавита подряд.

Что касается названий курса, то ищется а-я верхнего и нижнего регистров. Здесь предполагается то, что названия каждого курса будет содержаться хотя бы из четырех символов.

Понятие метасимволов в Python

Метасимволы – это специальные символы, которые могут иметь особое значение. Давайте рассмотрим наиболее часто используемые.

[] Используется для того, чтобы задавать символы для поиска вхождений.
\ Говорит о специальном символе (кроме этого, может использоваться для экранирования специальных символов).
. Характеризует все символы, за исключением новой строки.
^ Задает начало строки.
$ Задает окончание строки.
* Необходим, чтобы задать 0 и более вхождений.
+ Используется, чтобы задать 1 и более вхождений.
{} Применяется для задания требуемого количества вхождений.
| Нужен для указания одного из нескольких вариантов.
() Используется для группировки шаблона

Понятие комбинаций регулярных выражений

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

[arn] С его помощью можно получить совпадение, в котором имеется один из символов, которые включены в квадратные скобки.
[a-n] Возвращает совпадение между a и n. 
[^arn] Используется для получения совпадений, где имеется любой знак, за исключением заданных.
[0-9] Ищет те совпадения, в которых содержится цифра в заданном диапазоне.
[0-5][0-9] Используется для получения совпадения с двузначными числами. В зависимости от того, в каких квадратных скобках указано число, оно может быть любым в диапазоне между 0 и 59 (в этом случае).
[a-zA-Z] Возвращает совпадения, которые соответствуют и строчным, и прописным буквам английского алфавита в заданном диапазоне.
[а-ЯА-ЯёЁ] Используется для получения совпадения с любым символом, находящимся в пределах нужного соответствия. И строчные буквы, и прописные включаются сюда.
[+] Здесь + будет просто искать +.

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

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

ОфисГуру
Adblock
detector