Содержание

Модуль Python Re на примерах + задания и шаблоны ~ PythonRu

Регулярные выражения, также называемые regex, синтаксис или, скорее, язык для поиска, извлечения и работы с определенными текстовыми шаблонами большего текста. Он широко используется в проектах, которые включают проверку текста, NLP (Обработка естественного языка) и интеллектуальную обработку текста.

Введение в регулярные выражения

Регулярные выражения, также называемые regex, используются практически во всех языках программирования. В python они реализованы в стандартном модуле re.
Он широко используется в естественной обработке языка, веб-приложениях, требующих проверки ввода текста (например, адреса электронной почты) и почти во всех проектах в области анализа данных, которые включают в себя интеллектуальную обработку текста.

Эта статья разделена на 2 части.

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

Итак, сначала вы познакомитесь с 5 основными функциями модуля re, а затем посмотрите, как создавать регулярные выражения в python.
Узнаете, как построить практически любой текстовый шаблон, который вам, скорее всего, понадобится при работе над проектами, связанными с поиском текста.

Что такое шаблон регулярного выражения и как его скомпилировать?

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

Основным примером является \s+.
Здесь \ s соответствует любому символу пробела. Добавив в конце оператор +, шаблон будет иметь не менее 1 или более пробелов. Этот шаблон будет соответствовать даже символам tab \t.

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

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

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

Как разбить строку, разделенную регулярным выражением?

Рассмотрим следующий фрагмент текста.

>>> text = """100 ИНФ  Информатика
213 МАТ  Математика  
156 АНГ  Английский"""

У меня есть три курса в формате “[Номер курса] [Код курса] [Название курса]”. Интервал между словами разный.

Передо мной стоит задача разбить эти три предмета курса на отдельные единицы чисел и слов. Как это сделать?
Их можно разбить двумя способами:

  • Используя метод re.split.
  • Вызвав метод split для объекта regex.
# Разделит текст по 1 или более пробелами  
>>> re.split('\s+', text)  
# или
>>> regex.split(text)  
['100', 'ИНФ', 'Информатика', '213', 'МАТ', 'Математика', '156', 'АНГ', 'Английский']

Оба эти метода работают. Но какой же следует использовать на практике?
Если вы намерены использовать определенный шаблон несколько раз, вам лучше скомпилировать регулярное выражение, а не использовать re.split множество раз.

Поиск совпадений с использованием findall, search и match

Предположим, вы хотите извлечь все номера курсов, то есть 100, 213 и 156 из приведенного выше текста. Как это сделать?

Что делает 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()

Как понятно из названия, regex.search() ищет шаблоны в заданном тексте.
Но, в отличие от findall, который возвращает согласованные части текста в виде списка, regex.search() возвращает конкретный объект соответствия. Он содержит первый и последний индекс первого соответствия шаблону.

Аналогично, regex.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

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

Для изменения текста, используйте regex.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). Шаблон проверяет наличие символа новой строки, в python это \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. Добавление символа + в конце заставляет найти по крайней мере 1 соответствие цифрам 0-9. Если вы уверены, что номер курса, будет иметь ровно 3 цифры, шаблон мог бы быть [0-9] {3}.

Для кода курса, как вы могли догадаться, [А-ЯЁ]{3} будет совпадать с 3 большими буквами алфавита А-Я подряд (буква “ё” не включена в общий диапазон букв).


Для названий курса, [а-яА-ЯёЁ]{4,} будем искать а-я верхнего и нижнего регистра, предполагая, что имена всех курсов будут иметь как минимум 4 символа.

Можете ли вы догадаться, каков будет шаблон, если максимальный предел символов в названии курса, скажем, 20?
Теперь мне нужно написать 3 отдельные строки, чтобы разделить предметы. Но есть лучший способ. Группы регулярных выражений.
Поскольку все записи имеют один и тот же шаблон, вы можете создать единый шаблон для всех записей курса и внести данные, которые хотите извлечь из пары скобок ().

# создайте группы шаблонов текста курса и извлеките их
>>> course_pattern = '([0-9]+)\s*([А-ЯЁ]{3})\s*([а-яА-ЯёЁ]{4,})'  
>>> re.findall(course_pattern, text)  
[('100', 'ИНФ', 'Информатика'), ('213', 'МАТ', 'Математика'), ('156', 'АНГ', 'Английский')]

Обратите внимание на шаблон номера курса: [0-9]+, код: [А-ЯЁ]{3} и название: [а-яА-ЯёЁ]{4,} они все помещены в круглую скобку (), для формирования группы.

Что такое “жадное” соответствие в регулярных выражениях?

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

Давайте рассмотрим пример фрагмента HTML, где нам необходимо получить тэг HTML.

>>> text = "Пример жадного соответствия регулярных выражений"  
>>> re.findall('', text)  
['Пример жадного соответствия регулярных выражений']

Вместо совпадения до первого появления ‘>’, которое, должно было произойти в конце первого тэга тела, он извлек всю строку. Это по умолчанию “жадное” соответствие, присущее регулярным выражениям.

С другой стороны, ленивое соответствие “берет как можно меньше”. Это можно задать добавлением ? в конец шаблона.

>>> re.findall('', text)  
['', '']

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

re.search('', text).group()  
''

Наиболее распространенный синтаксис и шаблоны регулярных выражений

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

Основной синтаксис

.Один символ кроме новой строки
\.Просто точка ., обратный слеш \ убирает магию всех специальных символов.
\dОдна цифра
\DОдин символ кроме цифры
\wОдин буквенный символ, включая цифры
\WОдин символ кроме буквы и цифры
\sОдин пробельный (включая таб и перенос строки)
\SОдин не пробельный символ
\bГраницы слова
\nНовая строка
\tТабуляция

Модификаторы

$Конец строки
^Начало строки
ab|cdСоответствует ab или de. ab-d]Любой символ, кроме: a, b, c, d
()Извлечение элементов в скобках
(a(bc))Извлечение элементов в скобках второго уровня

Повторы

[ab]{2}2 непрерывных появления a или b
[ab]{2,5}от 2 до 5 непрерывных появления a или b
[ab]{2,}2 и больше непрерывных появления a или b
+одно или больше
*0 или больше
?0 или 1

Примеры регулярных выражений

Любой символ кроме новой строки

>>> text = 'python.org'  
>>> print(re.findall('.', text)) # Любой символ кроме новой строки  
['p', 'y', 't', 'h', 'o', 'n', '.', 'o', 'r', 'g']
>>> print(re.findall('...', text))
['pyt', 'hon', '.or']

Точки в строке

>>>text = 'python. \.]', text)) # соответствует всему кроме точки
['p', 'y', 't', 'h', 'o', 'n', 'o', 'r', 'g']

Любая цифра

>>> text = '01, Янв 2018'  
>>> print(re.findall('\d+', text)) # Любое число (1 и более цифр подряд)  
['01', '2018']

Все, кроме цифры

>>> text = '01, Янв 2018'  
>>> print(re.findall('\D+', text)) # Любая последовательность, кроме цифр  
[', Янв ']

Любая буква или цифра


>>> text = '01, Янв 2018'  
>>> print(re.findall('\w+', text)) # Любой символ(1 или несколько подряд) 
['01', 'Янв', '2018']

Все, кроме букв и цифр

>>> text = '01, Янв 2018'  
>>> print(re.findall('\W+', text)) # Все кроме букв и цифр  
[', ', ' ']

Только буквы

>>> text = '01, Янв 2018'  
>>> print(re.findall('[а-яА-ЯёЁ]+', text)) # Последовательность букв русского алфавита
['Янв']

Соответствие заданное количество раз

>>> text = '01, Янв 2018'  
>>> print(re. findall('\d{4}', text)) # Любые 4 цифры подряд
['2018'] 
>>> print(re.findall('\d{2,4}', text))  
['01', '2018']

1 и более вхождений

>>> print(re.findall(r'Co+l', 'So Cooool')) # 1 и более буква 'o' в строке
['Cooool']

Любое количество вхождений (0 или более раз)

>>> print(re.findall(r'Pi*lani', 'Pilani'))  
['Pilani']

0 или 1 вхождение

>>> print(re.findall(r'colou?r', 'color'))  
['color']

Граница слова
Границы слов \b обычно используются для обнаружения и сопоставления началу или концу слова. То есть, одна сторона является символом слова, а другая сторона является пробелом и наоборот.

Например, регулярное выражение \btoy совпадает с ‘toy’ в ‘toy cat’, но не в ‘tolstoy’. Для того, чтобы ‘toy’ соответствовало ‘tolstoy’, используйте toy\b.
Можете ли вы придумать регулярное выражение, которое будет соответствовать только первой ‘toy’в ‘play toy broke toys’? (подсказка: \ b с обеих сторон)
Аналогично, \ B будет соответствовать любому non-boundary( без границ).
Например, \ Btoy \ B будет соответствовать ‘toy’, окруженной словами с обеих сторон, как в ‘antoynet’.

>>> re.findall(r'\btoy\b', 'play toy broke toys') # соедини toy с ограничениями с обеих сторон 
['toy']

Практические упражнения

Давайте немного попрактикуемся. Пришло время открыть вашу консоль. (Варианты ответов здесь)

1. Извлеките никнейм пользователя, имя домена и суффикс из данных email адресов.

emails = """[email protected]  
[email protected]  
[email protected]"""  
# требуеый вывод
[('zuck26', 'facebook', 'com'), ('page33', 'google', 'com'), ('jeff42', 'amazon', 'com')]

2. Извлеките все слова, начинающиеся с ‘b’ или ‘B’ из данного текста.

text = """Betty bought a bit of butter, But the butter was so bitter, So she bought some better butter, To make the bitter butter better."""
# требуеый вывод
['Betty', 'bought', 'bit', 'butter', 'But', 'butter', 'bitter', 'bought', 'better', 'butter', 'bitter', 'butter', 'better']  

3. Уберите все символы пунктуации из предложения

sentence = """A, very very; irregular_sentence"""  
# требуеый вывод
A very very irregular sentence

4. Очистите следующий твит, чтобы он содержал только одно сообщение пользователя. То есть, удалите все URL, хэштеги, упоминания, пунктуацию, RT и CC.

tweet = '''Good advice! RT @TheNextWeb: What I would do differently if I was learning to code today https://t.co/lbwej0pxOd cc: @garybernhardt #rstats'''  
# требуеый вывод
'Good advice What I would do differently if I was learning to code today'
  1. Извлеките все текстовые фрагменты между тегами с HTML страницы: https://raw.githubusercontent.com/selva86/datasets/master/sample.html
    Код для извлечения HTML страницы:
import requests  
r = requests.get("https://raw.githubusercontent.com/selva86/datasets/master/sample.html")  
r.text # здесь хранится html
# требуеый вывод
['Your Title Here', 'Link Name', 'This is a Header', 'This is a Medium Header', 'This is a new paragraph! ', 'This is a another paragraph!', 'This is a new sentence without a paragraph break, in bold italics. ']

Ответы

# 1 задание
>>> pattern = r'(\w+)@([A-Z0-9]+)\.([A-Z]{2,4})'  
>>> re.findall(pattern, emails, flags=re.IGNORECASE)  
[('zuck26', 'facebook', 'com'), ('page33', 'google', 'com'), ('jeff42', 'amazon', 'com')]

Есть больше шаблонов для извлечения домена и суфикса. Это лишь один из них.


# 2 задание
>>> import re  
>>> re.findall(r'\bB\w+', text, flags=re.IGNORECASE)  
['Betty', 'bought', 'bit', 'butter', 'But', 'butter', 'bitter', 'bought', 'better', 'butter', 'bitter', 'butter', 'better']  

\b находится слева от ‘B’, значит слово должно начинаться на ‘B’.
Добавьте flags=re.IGNORECASE, что бы шаблон был не чувствительным к регистру.


# 3 задание
>>> import re  
>>> " ".join(re.split('[;,\s_]+', sentence))  
'A very very irregular sentence'  

# 4 задание
>>> import re  
>>> def clean_tweet(tweet):  
		tweet = re. _`{|}~"""), '', tweet) # удалит символы пунктуации
		tweet = re.sub('\s+', ' ', tweet) # заменит пробельные символы на 1 пробел 
		return tweet  
	
>>> print(clean_tweet(tweet)) 
'Good advice What I would do differently if I was learning to code today'

# 5 задание
>>> re.findall('(.*)*?>', r.text)  
['Your Title Here', 'Link Name', 'This is a Header', 'This is a Medium Header', 'This is a new paragraph! ', 'This is a another paragraph!', 'This is a new sentence without a paragraph break, in bold italics.']

Надеемся, информация была вам полезна. Стояла цель — познакомить вас с примерами регулярных выражений легким и доступным для запоминания способом.

Регулярные выражения в Python для новичков – База знаний Timeweb Community

У вас когда-нибудь возникала потребность в поиске строк, слов или даже символов в тексте?

В этой статье вы узнаете о регулярных выражениях в Python и научитесь работать с модулем «re», который позволяет совершать массу сравнительных и поисковых действий с текстом!

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

Регулярное выражение – это средство работы с текстом, которое позволяет по заданному «паттерну» искать и редактировать искомое слово/строку в тексте.

Комьюнити теперь в Телеграм

Подпишитесь и будьте в курсе последних IT-новостей

Подписаться

Импортируем модуль «re»

Для начала работы нам нужно импортировать модуль.

Модуль «re» устанавливать не нужно, он устанавливается вместе с самим Python. Нам лишь нужно импортировать его в проект.

Для этого в начале строки пропишем:


import re

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

re.match() – ищет совпадения в тексте, по умолчанию в начале строки.


import re

pattern = ‘34’
testString = ’12 timeweb 34 community 58’
result = re.search(pattern, testString)

print(result)
# Результат None, если совпадения будут обнаружены - result вернет их.

re.findall() – возвращает все строки, где было обнаружено совпадение.


import re

pattern = ‘\d+’ (ищем только числа с помощью метасимволов, об этом далее)
testString = ’12 timeweb 34 community 58’
result = re. findall(pattern, testString)

print(result)
# Результат [‘12’, ‘34’, ‘58’], если совпадения не будут обнаружены - то []

re.split() – разбивает строки по заданному паттерну и возвращает разбитые строки.


import re

pattern = ‘\d+’
testString = ’12 timeweb 34 community 58’
result = re.split(pattern, testString)

print(result)
# Результат [‘timeweb’, ‘community’], если совпадения не будут обнаружены - то []

re.sub() – заменяет символы по заданному паттерну на заданные символы и возвращает исправленную строку.


import re

pattern = ‘timeweb’
replace = ‘hello’
testString = ’timeweb community of timeweb community’
result = re.sub(pattern, replace, testString)

print(result)
# Результат ‘hello community of hello community’, если совпадения не будут обнаружены, то вернется первоначальная строка.

re. 0-9]’.

  • \s — находит совпадения при наличии пробелов в тексте.
  • \S — находит совпадения при отсутствии пробелов в тексте.
  • Надеюсь, что данная статья помогла вам разобраться с основами регулярных выражений в Python. Спасибо за внимание!

    Совпадение с началом строки

    $

    Совпадение с концом строки

    *

    Совпадение с 0 или более повторениями

    +

    Совпадение с 1 или более повторениями

    90 002 ?

    Совпадение с 0 или 1 повторением

    Специальные последовательности I

    \A

    Совпадение только с началом строки

    \b

    Совпадение с пустой строкой, только с началом или концом слова 9 0005

    Совпадение с пустой строкой, только если она не находится в начале или в конце слова 90-9]

    Символы II

    *?

    Совпадение 0 или более повторений не жадный

    +?

    Совпадение с 1 или более повторениями без жадности

    ??

    Совпадение с 0 или 1 повторением без жадности

    \

    Специальные символы Escape

    []

    Совпадение с набором символов

    [a-z]

    Совпадение с любой строчной буквой ASCII

    [нижний-верхний]

    Сопоставьте набор символов от младших до верхних 9a-zA-Z0-9_]

    \Z

    Совпадение только в конце строки

    Символы III

    {m}

    Совпадение ровно m копий

    {m,n} 900 05

    Совпадение от м до n повторений

    {,n}

    Совпадение от 0 до n повторений

    {m,}

    Совпадение от m до бесконечности повторений

    {m,n}?

    Поиск от m до n нежадных повторений (как можно меньше)

    RE Методы I

    re. compile(pattern, flags)

    Компиляция регулярного выражения шаблона с флагами

    re.match(шаблон, строка)

    Поиск шаблона только в начале строки

    re.search(шаблон, строка)

    Поиск шаблона в любом месте строки

    re.split(шаблон, строка)

    Разделить строку по вхождениям шаблона

    re.sub(шаблон, строка2, строка)

    Заменить самые левые неперекрывающиеся вхождения шаблона в строке на строку str2

    Группы I

    (совпадение)

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

    (?:match)

    Скобка версии без захвата (совпадение не может быть получено позже)

    (?P)

    Группа захвата с именем «name»

    (?P=name)

    Группа обратной ссылки с именем «name» по тому же шаблону

    (?#comment)

    Комментарий

    Match Objects I

    9 0002 матч.группа («имя»)

    Возврат подгруппы «имя» совпадения

    match. groups()

    Возвращает кортеж, содержащий все подгруппы совпадения

    match.groupdict()

    Возвращает dict, содержащий все названные подгруппы совпадения

    match.start(group)

    Возвращает начальный индекс совпадения подстроки по Группа

    Match.end (Group)

    Индекс обратного конечного конца подстроения, сопоставленного группой

    Match.span (группа)

    Возврат 2-туалетных начальных и конечных показателей группы в матче

    Flags I

    (?)

    Нотация расширения (используется для установки флагов)

    a

    Флаг соответствия только для ASCII

    i

    Игнорировать флаг регистра флаг

    м

    Многострочный флаг

    s

    Точка соответствует всем флагам

    x

    Подробный флаг

    Lookahead / Behind I

    (?=match)

    Lookahead assertion — match если содержимое соответствует следующему, но не использует строку .

    (?!match)

    Утверждение отрицательного просмотра вперед — выполняется, если содержимое не соответствует следующему

    (?<=match)

    Положительное утверждение просмотра назад — соответствует, если текущей позиции в строке предшествует совпадение

    (?

    Отрицательное утверждение обратного просмотра — совпадает, если текущей позиции не предшествует совпадение

    (?(id/name)yes|no)

    Соответствует шаблону «да», если идентификатор или имя существует, в противном случае соответствует шаблону «нет»

    Подбор предметов II

    match. pos

    Значение pos, которое было передано в search() или match()

    match.endpos

    Значение endpos, которое было передано в search() или match()

    match.lastindex

    Целочисленный индекс последней совпавшей группы захвата

    match.lastgroup

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

    match.re

    Регулярное выражение, которое match() или search() создало это совпадение

    match.string

    Строка передается в match() или search()

    Методы RE II

    re.fullmatch(шаблон, строка)

    Соответствие шаблону, если вся строка соответствует регулярному выражению в виде списка строк

    re.finditer(шаблон, строка)

    Возвращает итератор, выдающий объекты сопоставления по непересекающимся совпадениям шаблона в строке

    re.subn(шаблон, строка2, строка)

    Заменяет большинство левых вхождений шаблона в строке с помощью str2, но возвращает кортеж из (newstring, # созданных подписок)

    re. purge()

    Очистить кэш регулярных выражений

    Понимание функций регулярных выражений Python с примерами — SitePoint 0335 Share

    Регулярные выражения (регулярные выражения) имеют особое значение последовательности символов, используемые для поиска или сопоставления шаблонов в строках, как объясняется в этом введении в регулярное выражение. Ранее мы показали, как использовать регулярные выражения с JavaScript и PHP. В центре внимания этой статьи — регулярное выражение Python, цель которой — помочь вам лучше понять, как работать с регулярными выражениями в Python.

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

    Модули регулярных выражений в Python: re и regex

    В Python есть два модуля — re и regex — которые облегчают работу с регулярными выражениями. Модуль re встроен в Python, а модуль regex был разработан Мэтью Барнеттом и доступен на PyPI. 9Модуль 0348 regex от Barnett разработан с использованием встроенного модуля re , и оба модуля имеют схожие функции. Они различаются по реализации. Встроенный модуль re является более популярным из двух, поэтому мы будем работать с этим модулем здесь.

    Встроенный модуль Python re

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

    Прежде чем мы сможем использовать модуль re , мы должны импортировать его в наш файл, как и любой другой модуль или библиотеку Python:

     import re
     

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

    Выбор функций.

    Модуль re имеет такие функции, как re.search() , re.match() и re.compile() , которые мы обсудим в первую очередь.

    re.search(шаблон, строка, флаги=0) vs re.match(шаблон, строка, флаги=0)

    re.search() и re.match() поиск по строке шаблон регулярного выражения Python и вернуть совпадение, если оно найдено, или None , если объект совпадения не найден.

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

    Документация Python re. search() :

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

    Документация Python re.match() :

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

    Давайте посмотрим на несколько примеров кода для дальнейшего пояснения:

     search_result = [re.search](http://re.search)(r'\d{2}', 'Я живу по адресу 22 Garden Road, East Legon' )
    печать (результат_поиска)
    печать (search_result. group())
    >>>>
    
    22
     
     match_result = re.match(r'\d{2}', 'Я живу по адресу Гарден-роуд, 22, Восточный Легон')
    печать (match_result)
    печать (match_result.group())
    >>>>
    Никто
    Traceback (последний последний вызов):
    Файл "/home/ini/Dev./sitepoint/regex.py", строка 4, в 
    печать (match_result.group())
    AttributeError: объект «NoneType» не имеет атрибута «группа»
     

    В приведенном выше примере было возвращено None , так как не было совпадения в начале строки. Ошибка AttributeError 9Ошибка 0349 была вызвана при вызове метода group() , потому что нет объекта соответствия:

     match_result = re.match(r'\d{2}', "45 автомобилей использовались для президентского конвоя")
    печать (match_result)
    печать (match_result.group())
    >>>>
    
    45
     

    С 45, объектом соответствия в начале строки, метод match() работает просто отлично.

    re.compile(шаблон, флаги=0)

    Компиляция () принимает заданный шаблон регулярного выражения и компилирует его в объект регулярного выражения, используемый для поиска соответствия в строке или тексте. Он также принимает флаг в качестве необязательного второго аргумента. Этот метод полезен, потому что объект регулярного выражения можно присвоить переменной и использовать позже в нашем коде Python. Всегда не забывайте использовать необработанную строку r"..." при создании объекта регулярного выражения Python.

    Вот пример того, как это работает:

     regex_object = re.compile(r'b[ae]t')
    mo = regex_object.search('Держу пари, вы бы не позволили летучей мыши быть вашим президентом')
    печать (regex_object)
    >>>>
    перекомпилировать('b[ae]t')
     

    re.fullmatch(шаблон, строка, флаги=0)

    Эта функция принимает два аргумента: строку, переданную как шаблон регулярного выражения, строку для поиска и необязательный аргумент флага. Объект соответствия возвращается, если вся строка соответствует заданному шаблону регулярного выражения. Если совпадений нет, возвращается None :

     regex_object = re.compile(r'Tech is the future')
    mo = regex_object.fullmatch('За технологиями будущее, присоединяйтесь сейчас')
    печать (мес.)
    print([mo.group](http://mo.group)())
    >>>>
    Никто
    Traceback (последний последний вызов):
    Файл "/home/ini/Dev./sitepoint/regex.py", строка 16, в 
    print([mo.group](http://mo.group)())
    AttributeError: объект «NoneType» не имеет атрибута «группа»
     

    Код вызывает ошибку AttributeError , так как нет совпадения строк.

    re.findall(шаблон, строка, флаги=0)

    Функция findall() возвращает список всех объектов соответствия, найденных в заданной строке. Он проходит по строке слева направо, пока не будут возвращены все совпадения. См. фрагмент кода ниже:

     regex_object = re.compile(r'[A-Z]\w+')
    mo = regex_object.findall('Выберите все слова, начинающиеся с заглавной буквы')
    печать (мес. )
    >>>>
    ['Выбрать', 'Слова', 'Начало', 'Заглавные']
     

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

    re.sub(pattern, repl, string, count=0, flags=0)

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

    Вот пример:

     regex_object = re.compile(r'не согласен')
    mo = regex_object.sub('agreded',"Основатель и генеральный директор не согласились с новым направлением развития компании, не согласились и инвесторы.")
    печать (мес.)
    >>>>
    Основатель и генеральный директор договорились о новом направлении компании, согласились и инвесторы. 
     

    subn(pattern, repl, string, count=0, flags=0)

    Функция subn() выполняет ту же операцию, что и sub() , но возвращает кортеж со строкой и номером замены сделанный. См. фрагмент кода ниже:

     regex_object = re.compile(r'не согласен')
    mo = regex_object.subn('agreded',"Основатель и генеральный директор не согласились с новым направлением компании, инвесторы тоже не согласились.")
    печать (мес.)
    >>>>
    («Основатель и генеральный директор договорились о новом направлении компании, инвесторы тоже согласились», 2)
     

    Объекты и методы сопоставления

    Объект соответствия возвращается, когда шаблон регулярного выражения соответствует заданной строке в объекте регулярного выражения search() или match() 9Метод 0349. Объекты Match имеют несколько методов, которые оказываются полезными при работе с регулярными выражениями в Python.

    Match.group([group1, …])

    Этот метод возвращает одну или несколько подгрупп объекта соответствия. Один аргумент вернет подгруппу сигнала; несколько аргументов вернут несколько подгрупп на основе их индексов. По умолчанию метод group() возвращает всю подстроку совпадения. Когда аргумент в group() больше или меньше, чем подгруппы, IndexError выдается исключение.

    Вот пример:

     regex_object = re.compile(r'(\+\d{3}) (\d{2} \d{3} \d{4})')
    mo = regex_object.search('Выберите код страны из номера телефона: +233 54 502 9074')
    печать ([мо.группа](http://мо.группа)(1))
    >>>>
    +233
     

    Аргумент 1 , переданный методу group(1) , как видно из приведенного выше примера, выбирает код страны для Ганы +233 . Вызов метода без аргумента или 0 в качестве аргумента возвращает все подгруппы объекта соответствия:

     regex_object = re.compile(r'(\+\d{3}) (\d{2} \d{3} \d{4}) ')
    mo = regex_object.search('Выберите номер телефона: +233 54 502 9074')
    print([mo.group](http://mo.group)())
    >>>>
    +233 54 502 9074
     

    Match.

    groups(по умолчанию=None)

    groups() возвращает кортеж подгрупп, соответствующих заданной строке. Группы шаблонов регулярных выражений всегда заключаются в круглые скобки — () — и эти группы возвращаются при совпадении как элементы кортежа:

     regex_object = re.compile(r'(\+\d{3}) (\d{2}) (\d{3}) (\d{4})')
    mo = regex_object.search('Выберите номер телефона: +233 54 502 9074')
    печать (мо.групп())
    >>>>
    («+233», «54», «502», «9074»)
     

    Match.start([group]) & Match.end([group])

    Метод start() возвращает начальный индекс, а метод end() возвращает конечный индекс объекта соответствия:

     regex_object = re.compile(r'\s\w+')
    mo = regex_object.search('Соответствует любому слову после пробела')
    print('Совпадение начинается в', mo.start(), 'и заканчивается', mo.end())
    print([mo.group](http://mo.group)())
    >>>>
    Матч начинается в 5 и заканчивается в 9любой
     

    В приведенном выше примере есть шаблон регулярного выражения для сопоставления любого символа слова после пробела. Найдено совпадение — 'любой' — начиная с позиции 5 и заканчивая 9.

    Pattern.search(string[ pos[ endpos]])

    Значение pos указывает позицию индекса, в которой выполняется поиск. для объекта соответствия должен начинаться. endpos указывает, где должен остановиться поиск соответствия. Значение как для pos , так и для endpos может быть передано в качестве аргументов в search() или match() методов после строки. Вот как это работает:

     regex_object = re.compile(r'[az]+[0-9]')
    mo = regex_object.search('найти буквенно-цифровой символ python3 в строке', 20 , 30)
    print([mo.group](http://mo.group)())
    >>>>
    питон3
     

    Приведенный выше код выбирает любой буквенно-цифровой символ в строке поиска.

    Поиск начинается с позиции индекса строки 20 и останавливается на позиции 30.

    re Regex Flags

    Python позволяет использовать флаги при использовании методов модуля re , таких как search() и match() , что дает больше контекста для регулярных выражений. Флаги — это необязательные аргументы, которые определяют, как механизм регулярных выражений Python находит объект соответствия.

    re.I (re.IGNORECASE)

    Этот флаг используется при выполнении поиска без учета регистра. Механизм регулярных выражений будет игнорировать варианты шаблонов регулярных выражений в верхнем или нижнем регистре:

     regex_object = [re.search](http://re.search)('django', 'Мой технический стек состоит из python, Django, MySQL, AWS , React', re.I)
    печать (regex_object.group())
    >>>>
    Джанго
     

    re.I гарантирует, что соответствующий объект будет найден, независимо от того, в верхнем или нижнем регистре он находится.

    re.S (re.DOTALL)

    '.' специальный символ соответствует любому символу, кроме новой строки. Введение этого флага также будет соответствовать новой строке в блоке текста или строки. См. пример ниже:

     regex_object= [re.search](http://re.search)('.+', 'Какой ваш любимый вкус кофе \nЯ предпочитаю мокко')
    печать (regex_object. group())
    >>>>
    Какой твой любимый вкус кофе
     

    '.' символов находит совпадение только с начала строки и останавливается на новой строке. Введение флага re.DOTALL будет соответствовать символу новой строки. См. пример ниже:

     regex_object= [re.search](http://re.search)('.+', 'Какой ваш любимый вкус кофе \nЯ предпочитаю мокко', re.S)
    печать (regex_object.group())
    >>>>
    Какой твой любимый вкус кофе
    я предпочитаю мокко
     

    re.M (re.MULTILINE)

    По умолчанию 9J\w+', 'Популярные языки программирования в 2022 году: \nPython \nJavaScript \nJava \nRust \nRuby', re.M) печать (regex_object.group()) >>>> JavaScript

    re.X (re.VERBOSE)

    Иногда шаблоны регулярных выражений Python могут быть длинными и запутанными. Флаг re.X помогает, когда нам нужно добавить комментарии в наш шаблон регулярного выражения. Мы можем использовать строковый формат ''' для создания многострочного регулярного выражения с комментариями:

     email_regex = [re. search](http://re.search)(r'''
    [a-zA-Z0-9._%+-]+ # имя пользователя, состоящее из буквенно-цифровых символов
    @ # @ символ
    [a-zA-Z0-9.-]+ # доменное имя содержит символы слова
    (\.[a-zA-Z]{2,4}) # точка-что-то
    ''', 'извлеките адрес электронной почты из этой строки [[email protected]](mailto:[email protected]) и отправьте электронное письмо', re.X)
    печать (email_regex.group ())
    >>>>
    [[email protected]](адрес электронной почты:[email protected])
     

    Практические примеры регулярных выражений в Python

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

    Поиск и замена Python в регулярном выражении файла

    Вот наша цель для этого примера:

    • Создать файл «pangram.txt».
    • Добавить простой текст в файл, «Пять волшебников бокса быстро карабкаются».
    • Напишите простое регулярное выражение Python для поиска и замены слова «взбираться» на слово «прыгать», чтобы получилась панграмма.

    Вот код для этого:

     #импорт модуля регулярных выражений
    импортировать повторно
    file_path="pangram.txt"
    текст = "подняться"
    сабы = "прыжок"
    # определение метода замены
    def search_and_replace (путь к файлу, текст, подписки, флаги = 0):
    с open(file_path, "r+") в качестве файла:
    #читаем содержимое файла
    file_contents = [file.read](http://file.read)()
    text_pattern = re.compile (re.escape (текст), флаги)
    file_contents = text_pattern.sub(subs, file_contents)
    [файл.искать](http://файл.искать)(0)
    файл.truncate()
    файл.записать (файл_содержимое)
    #вызов метода search_and_replace
    search_and_replace(file_path, text, subs)
     

    Регулярное выражение Python для парсинга веб-страниц

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

     import urllib.request
    phone_number_regex = r'\(\d{3}\) \d{3}-\d{4}'
    url = 'https://www. summet.com/dmsi/html/codesamples/addresses.html'
    # получить ответ
    ответ = urllib.request.urlopen(url)
    # преобразовать ответ в строку
    string_object = [response.read](http://response.read)().decode("utf8")
    # используем регулярное выражение для извлечения телефонных номеров
    regex_object = перекомпилировать (phone_regex)
    mo = regex_object.findall (string_object)
    # вывести 5 лучших телефонных номеров
    печать (мес [: 5])
    >>>>
    ['(257) 563-7401', '(372) 587-2335', ​​'(786) 713-8616', '(793) 151-6230, (492) 709-6392]
     

    Заключение

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

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