Содержание

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

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

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

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

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

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

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

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

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

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

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

Профессия Data Scientist
Профессия Data Scientist
>>> import re
>>> regex = re.compile('\s+')

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

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

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

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

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

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

  • Используя метод
    re.split
    .
  • Вызвав метод split для объекта regex.

>>> 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_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+ на один пробел .


>>> 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)  

>>> 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 = "<body>Пример жадного соответствия регулярных выражений</body>"  
>>> re.findall('<.*>', text)  
['<body>Пример жадного соответствия регулярных выражений</body>']

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

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

>>> re.findall('<.*?>', text)  
['<body>', '</body>']

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

re.search('<.*?>', text).group()  
'<body>'

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

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

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

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

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

$Конец строки
^Начало строки
ab|cdСоответствует ab или de.
[ab-d]Один символ: a, b, c, d
[^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.org'  
>>> print(re.findall('\.', text)) 
['.']
>>> print(re.findall('[^\.]', text)) 
['p', 'y', 't', 'h', 'o', 'n', 'o', 'r', 'g']

Любая цифра

>>> text = '01, Янв 2018'  
>>> print(re.findall('\d+', text)) 
['01', '2018']

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

>>> text = '01, Янв 2018'  
>>> print(re.findall('\D+', text)) 
[', Янв ']

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

>>> text = '01, Янв 2018'  
>>> print(re.findall('\w+', text)) 
['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)) 
['2018'] 
>>> print(re.findall('\d{2,4}', text))  
['01', '2018']

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

>>> print(re.findall(r'Co+l', 'So Cooool')) 
['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']

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

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

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 


['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.']

Ответы


>>> 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')]

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



>>> 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, что бы шаблон был не чувствительным к регистру.



>>> import re  
>>> " ".join(re.split('[;,\s_]+', sentence))  
'A very very irregular sentence'  


>>> import re  
>>> def clean_tweet(tweet):  
		tweet = re.sub('http\S+\s*', '', tweet) 
		tweet = re.sub('RT|cc', '', tweet) 
		tweet = re.sub('#\S+', '', tweet) 
		tweet = re.sub('@\S+', '', tweet) 
		tweet = re.sub('[%s]' % re.escape("""!"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~"""), '', tweet) 
		tweet = re.sub('\s+', ' ', tweet) 
		return tweet  
	
>>> print(clean_tweet(tweet)) 
'Good advice What I would do differently if I was learning to code today'


>>> 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.']

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

Документация по модулю Re для Python 3 на русском ~ PythonRu

Регулярные выражения — специальная последовательность символов, которая помогает сопоставлять или находить строки python с использованием специализированного синтаксиса, содержащегося в шаблоне. Регулярные выражения распространены в мире UNIX.

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

Давайте рассмотрим две функции, которые будут использоваться для обработки регулярных выражений. Важно так же заметить, что существуют символы, которые меняют свое значение, когда используются в регулярном выражении.Чтобы избежать путаницы при работе с регулярными выражениями, записывайте строку как r'expression'.

Функция match

Эта функция ищет pattern в string и поддерживает настройки с помощью дополнительного flags.
Ниже можно увидеть синтаксис данной функции:

re.match(pattern, string, flags=0)

Описание параметров:

Параметр & Описание
1pattern — строка регулярного выражения (r'g.{3}le')
2string — строка, в которой мы будем искать соответствие с шаблоном в начале строки ('google')
3flags — модификаторы, перечисленными в таблице ниже. Вы можете указать разные флаги с помощью побитового OR

Функция re.match возвращает объект match при успешном завершении, или None при ошибке. Мы используем функцию group(num) или groups() объекта match для получения результатов поиска.

Метод совпадения объектов и описание
1group(num=0) — этот метод возвращает полное совпадение (или совпадение конкретной подгруппы)
2groups() — этот метод возвращает все найденные подгруппы в tuple

Пример функции re.match

import re


title = "Error 404. Page not found"
exemple = re.match( r'(.*)\. (.*?) .*', title, re.M|re.I)

if exemple:
   print("exemple.group() : ", exemple.group())
   print("exemple.group(1) : ", exemple.group(1))
   print("exemple.group(2) : ", exemple.group(2))
   print("exemple.groups():", exemple.groups())
else:
   print("Нет совпадений!")
Профессия Data ScientistПрофессия Data Scientist

Когда вышеуказанный код выполняется, он производит следующий результат:

exemple.group(): Error 404. Page not found
exemple.group(1): Error 404
exemple.group(2): Page
exemple.groups(): ('Error 404', 'Page')

Функция search

Эта функция выполняет поиск первого вхождения pattern внутри string с дополнительным flags.
Пример синтаксиса для этой функции:

re.search(pattern, string, flags=0)

Описание параметров:

Параметр & Описание
1pattern — строка регулярного выражения
2string — строка, в которой мы будем искать первое соответствие с шаблоном
3flags — модификаторы, перечисленными в таблице ниже. Вы можете указать разные флаги с помощью побитового OR

Функция re.search возвращает объект match если совпадение найдено, и None, когда нет совпадений. Используйте функцию group(num) или groups() объекта match для получения результата функции.

Способы совпадения объектов и описание
1group(num=0) — метод, который возвращает полное совпадение (или же совпадение конкретной подгруппы)
2groups() — метод возвращает все сопоставимые подгруппы в tuple

Пример функции re.search

import re


title = "Error 404. Page not found"

exemple = re.search( r' (.*)\. (.*?) .*', title, re.M|re.I)

if exemple:
   print("exemple.group():", exemple.group())
   print("exemple.group(1):", exemple.group(1))
   print("exemple.group(2):", exemple.group(2))
   print("exemple.groups():", exemple.groups())
else:
   print("Нет совпадений!")

Запускаем скрипт и получаем следующий результат:

exemple.group():  404. Page not found
exemple.group(1): 404
exemple.group(2): Page
exemple.groups(): ('404', 'Page')

Match и Search

Python предлагает две разные примитивные операции, основанные на регулярных выражениях: match выполняет поиск паттерна в начале строки, тогда как search выполняет поиск по всей строке.

Пример разницы re.match и re.search

import re


title = "Error 404. Page not found"
match_exemple = re.match( r'not', title, re.M|re.I)

if match_exemple:
   print("match --> match_exemple.group():", match_exemple.group())
else:
   print("Нет совпадений!")

search_exemple = re.search( r'not', title, re.M|re.I)
if search_exemple:
   print("search --> search_exemple.group():", search_exemple.group())
else:
   print("Нет совпадений!")

Когда этот код выполняется, он производит следующий результат:

Нет совпадений!
search --> search_exemple.group(): not

Метод Sub

Одним из наиболее важных методов модуля re, которые используют регулярные выражения, является re.sub.
Пример синтаксиса sub:

re.sub(pattern, repl, string, max=0)

Этот метод заменяет все вхождения pattern в string на repl, если не указано на max. Он возвращает измененную строку.

Пример

import re


born = "05-03-1987 # Дата рождения"


dob = re.sub(r'#.*$', "", born)
print("Дата рождения:", dob)


f_dob = re.sub(r'-', ".", born)    
print(f_dob)

Запускаем скрипт и получаем вывод:

Дата рождения: 05-03-1987 
05.03.1987 # Дата рождения

Модификаторы регулярных выражений: flags

Функции регулярных выражений включают необязательный модификатор для управления изменения условий поиска. Модификаторы задают в необязательном параметре flags. Несколько модификаторов задают с помощью побитового ИЛИ (|), как показано в примерах выше.

Модификатор & Описание
1re.I — делает поиск нечувствительным к регистру
2re.L — ищет слова в соответствии с текущим языком. Эта интерпретация затрагивает алфавитную группу (\w и \W), а также поведение границы слова (\b и \B).
3re.M — символ $ выполняет поиск в конце любой строки текста (не только конце текста) и символ ^ выполняет поиск в начале любой строки текста (не только в начале текста).
4re.S — изменяет значение точки (.) на совпадение с любым символом, включая новую строку
5re.U— интерпретирует буквы в соответствии с набором символов Unicode. Этот флаг влияет на поведение \w, \W, \b, \B. В python 3+ этот флаг установлен по умолчанию.
6re.X— позволяет многострочный синтаксис регулярного выражения. Он игнорирует пробелы внутри паттерна (за исключением пробелов внутри набора [] или при экранировании обратным слешем) и обрабатывает не экранированный “#” как комментарий.

Шаблоны регулярных выражений

За исключением символов (+?. * ^ $ () [] {} | ), все остальные соответствуют самим себе. Вы можете избежать экранировать специальный символ с помощью бэкслеша (/).

В таблицах ниже описаны все символы и комбинации символов для регулярных выражений, которые доступны в Python:

Шаблон & Описание
1^ — соответствует началу строки.
2$— соответствует концу строки.
3. — соответствует любому символу, кроме новой строки. Использование флага re.M позволяет также соответствовать новой строке.
4[4fw] — соответствует любому из символов в скобках.
5[^4fw] — соответствует любому символу, кроме тех, что в квадратных скобках.
6foo* — соответствует 0 или более вхождений “foo”.
7bar+ —- соответствует 1 или более вхождениям “bar”.
8foo? —- соответствует 0 или 1 вхождению “foo”.
9bar{3} —- соответствует трем подряд вхождениям “bar”.
10foo{3,} — соответствует 3 или более вхождениям “foo”.
11bar{2,5} —- соответствует от 2 до 5 вхождениям “bar”.
12a|b — соответствует либо a, либо b.
13(foo) — группирует регулярные выражения.
14(?imx) — временно включает параметры i, m или x в регулярное выражение. Если используются круглые скобки — затрагивается только эта область.
15(?-imx) — временно отключает опции i, m или x в регулярном выражении. Если используются круглые скобки — затрагивается только эта область.
16(?: foo) — Группирует регулярные выражения без сохранения совпадающего текста.
17(?imx: re) — Временно включает параметры i, m или x в круглых скобках.
18(?-imx: re) — временно отключает опции i, m или x в круглых скобках.
19(?#…) — комментарий.
20(?= foo) — совпадает со всеми словами после которых » foo».
21(?! foo) — совпадает со всеми словами после которых нет » foo».
22(?> foo) — совпадает со всеми словами перед которыми » foo».
23\w — совпадает с буквенным символом.
24\W — совпадает с не буквенным символом.
25\s — совпадает с пробельными символами (\t, \n, \r, \f и пробелом).
26\S — все кроме пробельных символов.
27\d — соответствует цифрам (0-9).
28\D — все кроме цифры.
29\A — соответствует началу строки.
30\Z – соответствует концу строки. Включая перевод на новую строку, если такая есть.
31\z — соответствует концу строки.
32\G — соответствует месту, где закончилось последнее соответствие.
33\b — соответствует границам слов, когда поставлены внешние скобки.
34\B — все кроме границы слова.
35**\n,\t,\r,\f ** — соответствует новым строкам, подстрокам.
36\1…\9 — соответствует подгруппе n-й группы.
37\10 — соответсвуйет номеру группы. В противном случае относится к восьмеричному представлению символьного кода.

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

Поиск по буквам

python – находит “python”. |

Поиск по наборам символов

Паттерн & Результаты
1[Pp]ython соответствует “Python” и “python”
2rub[ye] соответствует “ruby” и “rube”
3[aeiou] Соответствует любой гласной нижнего регистра английского алфавита ([ауоыиэяюёе] для русского)
4[0-9] соответствует любой цифре; так же как и [0123456789]
5[a-z] соответствует любой строчной букве ASCII (для кириллицы [а-яё])
6[A-Z] соответствует любой прописной букве ASCII (для кириллицы [А-ЯЁ])
7[a-zA-Z0-9] соответствует всем цифрам и буквам
8[^aeiou] соответствует всем символам, кроме строчной гласной
9[^0-9] Соответствует всем символам, кроме цифр

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

Пример & Описание
1. соответствует любому символу, кроме символа новой строки
2\d соответствует цифрам: [0-9]
3\D не соответствует цифрам: [^0-9]
4\s соответствует пробельным символам: [\t\r\n\f]
5\S не соответствует пробельным символам: [^ \t\r\n\f]
6\w соответствует одному из буквенных символов: [A-Za-z0-9_]
7\W не соответствует ни одному из буквенных символов: [^A-Za-z0-9_]

Случаи повторения

Примеры
1ruby? совпадает с “rub” и “ruby”: “y” необязателен
2ruby* совпадает с “rub” и “rubyyyyy”: “y” необязателен и может повторятся несколько раз
3ruby+ совпадает с “ruby”: “y” обязателен
4\d{3} совпадает с тремя цифрами подряд
5\d{3,} совпадает с тремя и более цифрами подряд
6\d{3,5} совпадает с 3,4,5 цифрами подряд

Жадный поиск

Пример & Описание
1<.*> Жадное повторение: соответствует “perl>”
2<.*?> Ленивый поиск: соответствует “” в “perl>”

Группирование со скобками

Пример & Описание
1\D\d+ Нет группы: + относится только к \d
2(\D\d)+ Группа: + относится к паре \D\d
3([Pp]ython(, )?)+ соответствует “Python”, “Python, python, python”.

Ссылки на группы

Пример & Описание
1([Pp])ython&\1ails совпадает с python&pails и Python&Pails
2([’»])[^\1]*\1 Строка с одним или двумя кавычками. \1 соответствует 1-й группе. \2 соответствует второй группе и т. д.

Или

Пример & Описание
1python|perl соответствует “python” или “perl”
2rub(y|le)) соответствует “ruby” или “ruble”
3Python(!+|?) после «Python» следует 1 и более “!” или один “?”

Границы слов и строк

Пример & Описание
1^Python соответствует “Python” в начале текста или новой строки текста.
2Python$ соответствует “Python” в конце текста или строки текста.
3\APython соответствует “Python” в начале текста
4Python\Z соответствует “Python” в конце текста
5\bPython\b соответствует “Python” как отдельному слову
6\brub\B соответствует «rub» в начале слова: «rube» и «ruby».
7Python(?=!) соответствует “Python”, если за ним следует восклицательный знак.
8Python(?!!) соответствует “Python”, если за ним не следует восклицательный знак

Специальный синтаксис в группах

Пример & Описание
1R(?#comment) соответствует «R». Все, что следует дальше — комментарий
2R(?i)uby нечувствительный к регистру при поиске “uby”
3R(?i:uby) аналогично указанному выше
4rub(?:y le)) группируется только без создания обратной ссылки (\1)

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

Регулярные выражения – это небольшой язык, который вы можете использовать внутри Python и многих других языках программирования. Зачастую регулярные выражения упоминаются как “regex”, “regexp” или просто “RE”, от reuglar expressions. Такие языки как Perl и Ruby фактически поддерживают синтаксис регулярных выражений прямо в собственном языке. Python же поддерживает благодаря библиотеки, которую вам нужно импортировать. Основное использование регулярных выражений – это сопоставление строк. Вы создаете правила сопоставления строк, используя регулярные выражения, после чего вы применяете их в строке, чтобы увидеть, присутствуют ли какие-либо сопоставления. «Язык» регулярных выражений на самом деле весьма короткий, так что вы вряд ли сможете использовать для всех своих нужд при сопоставлении строк. Кроме того, работая с задачами, в которых вы используете регулярные выражения, вы можете заметно усложнить процесс, а лечение багов в таком случае очень трудоемкое. В таких случаях вам нужно просто использовать Python.

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

Согласуемые символы

Когда вам нужно найти символ в строке, в большей части случаев вы можете просто использовать этот символ или строку. Так что, когда нам нужно проверить наличие слова «dog», то мы будем использовать буквы в dog. Конечно, существуют определенные символы, которые заняты регулярными выражениями. Они так же известны как метасимволы. Внизу изложен полный список метасимволов, которые поддерживают регулярные выражения Python:

. ˆ $ * + ? { } [ ] | ( )

. ˆ $ * + ? { } [ ] | ( )

Давайте взглянем как они работают. Основная связка метасимволов, с которой вы будете сталкиваться, это квадратные скобки: [ и ]. Они используются для создания «класса символов», который является набором символов, которые вы можете сопоставить. Вы можете отсортировать символы индивидуально, например, так: [xyz]. Это сопоставит любой внесенный в скобки символ. Вы также можете использовать тире для выражения ряда символов, соответственно: [a-g]. В этом примере мы сопоставим одну из букв в ряде между a и g. Фактически для выполнения поиска нам нужно добавить начальный искомый символ и конечный. Чтобы упростить это, мы можем использовать звездочку. Вместо сопоставления *, данный символ указывает регулярному выражению, что предыдущий символ может быть сопоставлен 0 или более раз. Давайте посмотрим на пример, чтобы лучше понять о чем речь:

Этот шаблон регулярного выражения показывает, что мы ищем букву а, ноль или несколько букв из нашего класса, [b-f] и поиск должен закончиться на f. Давайте используем это выражение в Python:

import re text = ‘abcdfghijk’ parser = re.search(‘a[b-f]*f’) print(parser.group()) # ‘abcdf’

import re

text = ‘abcdfghijk’

 

parser = re.search(‘a[b-f]*f’)

print(parser.group()) # ‘abcdf’

В общем, это выражение просмотрит всю переданную ей строку, в данном случае это abcdfghijk.
Выражение найдет нашу букву «а» в начале поиска. Затем, в связи с тем, что она имеет класс символа со звездочкой в конце, выражение прочитает остальную часть строки, что бы посмотреть, сопоставима ли она. Если нет, то выражение будет пропускать по одному символу, пытаясь найти совпадения. Вся магия начинается, когда мы вызываем поисковую функцию модуля re. Если мы не найдем совпадение, тогда мы получим None. В противном случае, мы получим объект Match. Чтобы увидеть, как выглядит совпадение, вам нужно вызывать метод group. Существует еще один повторяемый метасимвол, аналогичный *. Этот символ +, который будет сопоставлять один или более раз. Разница с *, который сопоставляет от нуля до более раз незначительна, на первый взгляд.

Символу + необходимо как минимум одно вхождение искомого символа. Последние два повторяемых метасимвола работают несколько иначе. Рассмотрим знак вопроса «?», применение которого выгладит так: “co-?op”. Он будет сопоставлять и “coop” и “co-op”. Последний повторяемый метасимвол это {a,b}, где а и b являются десятичными целыми числами. Это значит, что должно быть не менее «а» повторений, но и не более «b». Вы можете попробовать что-то на подобии этого:

Это очень примитивный пример, но в нем говорится, что мы сопоставим следующие комбинации: xbz, xbbz, xbbbz и xbbbbz, но не xz, так как он не содержит «b».

Следующий метасимвол это ^. Этот символ позволяет нам сопоставить символы которые не находятся в списке нашего класса. Другими словами, он будет дополнять наш класс. Это сработает только в том случае, если мы разместим ^ внутри нашего класса. Если этот символ находится вне класса, тогда мы попытаемся найти совпадения с данным символом. Наглядным примером будет следующий: [ˆa]. Так, выражения будет искать совпадения с любой буквой, кроме «а». Символ ^ также используется как анкор, который обычно используется для совпадений в начале строки.

Существует соответствующий якорь для конце строки – «$». Мы потратим много времени на введение в различные концепты применения регулярных выражений. В следующих параграфах мы углубимся в более подробные примеры кодов.

Поиск сопоставлений шаблонов

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

import re text = «The ants go marching one by one» strings = [‘the’, ‘one’] for string in strings: match = re.search(string, text) if match: print(‘Found «{}» in «{}»‘.format(string, text)) text_pos = match.span() print(text[match.start():match.end()]) else: print(‘Did not find «{}»‘.format(string))

import re

 

text = «The ants go marching one by one»

 

strings = [‘the’, ‘one’]

 

for string in strings:

    match = re.search(string, text)

    if match:

        print(‘Found «{}» in «{}»‘.format(string, text))

        text_pos = match.span()

        print(text[match.start():match.end()])

    else:

        print(‘Did not find «{}»‘.format(string))

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

Существует несколько других функций, которые нужно прояснить в данном примере. Обратите внимание на то, что мы вызываем span. Это дает нам начальную и конечную позицию совпавшей строки. Если вы выведите text_pos, которому мы назначили span, вы получите кортеж на подобие следующего: (21, 24). В качестве альтернативы вы можете просто вызвать методы сопоставления, что мы и сделаем далее. Мы используем начало и конец для того, чтобы взять начальную и конечную позицию сопоставления, это должны быть два числа, которые мы получаем из span.

Коды поиска

Существует несколько специальных выражений, которые вы можете искать, используя Python. Вот короткий список с кратким пояснением каждого кода:

  • \d соответствует цифре
  • \D соответствует не цифре
  • \s соответствует пустому полю (пробел)
  • \S соответствует заполненному полю
  • \w соответствует алфавитно-цифровому значению
  • \W соответствует не алфавитно-цифровому значению

Вы можете использовать эти коды внутри класса символа вот так: [\d]. Таким образом, это позволит нам найти любую цифру, находящейся в пределе от 0 до 9. Я настаиваю на том, чтобы вы попробовали остальные коды выхода лично.

Компилирование

Модуль re позволяет вам «компилировать» выражение, которое вы ищите чаще всего. Это также позволит вам превратить выражение в объект SRE_Pattern. Вы можете использовать этот объект в вашей функции поиска в будущем. Давайте используем код из предыдущего примера и изменим его, чтобы использовать компилирование:

import re text = «The ants go marching one by one» strings = [‘the’, ‘one’] for string in strings: regex = re.compile(string) match = re.search(regex, text) if match: print(‘Found «{}» in «{}»‘.format(string, text)) text_pos = match.span() print(text[match.start():match.end()]) else: print(‘Did not find «{}»‘.format(string))

import re

 

text = «The ants go marching one by one»

 

strings = [‘the’, ‘one’]

 

for string in strings:

    regex = re.compile(string)

    match = re.search(regex, text)

    if match:

        print(‘Found «{}» in «{}»‘.format(string, text))

        text_pos = match.span()

        print(text[match.start():match.end()])

    else:

        print(‘Did not find «{}»‘.format(string))

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

Флаги компиляции

Существует 7 флагов компиляции, которые содержатся в Python 3. Эти флаги могут изменить поведение вашего паттерна. Давайте пройдемся по каждому из них, затем рассмотрим, как их использовать.

re.A / re.ASCII

Флаг ASCII указывает Python сопоставлять против ASCII, вместо использования полного Юникода для сопоставления, в сочетании со следующими кодами: w, W, b, B, d, D, s и S. Также существует флаг re.U / re.UNICODE, который используется в целях обратной совместимости. В любом случае, эти флаги являются излишеством, так как Python выполняет сопоставления в Юникоде в автоматическом режиме.

re.DEBUG

Данный флаг показывает информацию о дебаге вашего скомпилированного выражения.

re.I / re.IGNORECASE

Если вам нужно выполнить сравнение без учета регистра, тогда этот флаг – то, что вам нужно. Если ваше выражение было [a-z] и вы скомпилировали его при помощи этого флага, то ваш паттерн сопоставит заглавные буквы в том числе. Это также работает для Юникода и не влияет на текущую локаль.

re.L / re.LOCALE

Данный флаг делает коды: w, W, b, B, d, D, s и S зависимыми от нынешней локали. Однако, в документации говорится, что вы не должны зависеть от данного флага, так как механизм локали сам по себе очень ненадежный. Вместо этого, лучше используйте сопоставление Юникода. Далее в документации говорится, что данный флаг имеет смысл использовать только в битовых паттернах.

re.M / re.MULTILINE

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

re.S / re.DOTALL

Этот забавный флаг указывает метасимволу «.» (период) сопоставить любой символ. Без этого флага, данный метасимвол будет сопоставлять все, что угодно, но не новую строку.

re.X / re.VERBOSE

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

Использование флага компиляции

Давайте уделим немного времени, и посмотрим на простой пример, в котором используется флаг компиляции VERBOSE. Неплохой пример – взять обычную электронную почту и использовать поиск регулярных выражений, таких как r’[w.-][email protected][w.-]+’ и добавить комментарии, используя флаг VERBOSE. Давайте посмотрим:

re.compile(»’ [\w\.-]+ @ [\w\.-]+’ »’, re.VERBOSE)

re.compile(»’

           [\w\.-]+

           @

           [\w\.-]+’

           »’,

           re.VERBOSE)

Давайте пройдем дальше и научимся находить множественные совпадения.

Находим множественные совпадения

До этого момента мы научились только находить первое совпадение в строке. Но что если у вас строка, в которой содержится множество совпадений? Давайте посмотрим, как найти одно:

import re silly_string = «the cat in the hat» pattern = «the» match = re.search(pattern, text) print(match.group()) # ‘the’

import re

 

silly_string = «the cat in the hat»

pattern = «the»

 

match = re.search(pattern, text)

print(match.group()) # ‘the’

Теперь, как вы видите, у нас есть два экземпляра слова the, но нашли мы только одно. Существует два метода, чтобы найти все совпадения. Первый, который мы рассмотрим, это использование функции findall:

import re silly_string = «the cat in the hat» pattern = «the» a = re.findall(pattern, silly_string) print(a) # [‘the’, ‘the’]

import re

 

silly_string = «the cat in the hat»

pattern = «the»

 

a = re.findall(pattern, silly_string)

print(a) # [‘the’, ‘the’]

Функция findall будет искать по всей переданной ей строке, и впишет каждое совпадение в список. По окончанию поиска вышей строки, она выдаст список совпадений. Второй способ найти несколько совпадений, это использовать функцию finditer:

import re silly_string = «the cat in the hat» pattern = «the» for match in re.finditer(pattern, silly_string): s = «Found ‘{group}’ at {begin}:{end}».format( group=match.group(), begin=match.start(), end=match.end()) print(s)

import re

 

silly_string = «the cat in the hat»

pattern = «the»

 

for match in re.finditer(pattern, silly_string):

    s = «Found ‘{group}’ at {begin}:{end}».format(

        group=match.group(), begin=match.start(),

        end=match.end())

    

    print(s)

Как вы могли догадаться, метод finditer возвращает итератор экземпляров Match, вместо строк, которые мы получаем от findall. Так что нам нужно немного подформатировать результаты перед их выводом. Попробуйте запустить данный код и посмотрите, как он работает.

Сложности с обратными косыми

Обратные косые немного усложняют жизнь в мире регулярных выражений Python. Это связанно с тем, что регулярные выражения используют обратные косые для определения специальных форм, или для того, чтобы искать определенный символ, вместо того, чтобы вызывать его. Как если бы мы искали символ доллара $. Если мы не используем обратную косую для этого, нам нужно просто создать анкор. Проблема возникает по той причине, что Python использует символ обратной косой по той же причине в литеральных строках.

Давайте представим, что вам нужно найти строку на подобии этой: «python». Для её поиска в регулярном выражении, вам нужно будет использовать обратную косую, но, так как Python также использует обратную косую, так что на выходе вы получите следующий поисковый паттерн: «\\python» (без скобок). К счастью, Python поддерживает сырые строки, путем подстановки буквы r перед строкой. Так что мы можем сделать выдачу более читабельной, введя следующее: r”\python”. Так что если вам нужно найти что-то с обратной косой в названии, убедитесь, что используете сырые строки для этой цели, иначе можете получить совсем не то, что ищете.

Подведем итоги

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

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

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

import re

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

Метод re.search()

Метод re.search() используется для нахождения первого вхождения заданного шаблона в строку.

Синтаксис: re.search(pattern, string, flags[optional])

Метод re.search() принимает на вход шаблон и строку и возвращает объект match в случае успеха, а в противном случае, если шаблон не был найден, возвращает None. Объект match имеет метод group(), который возвращает сам шаблон.

import re
s = "my number is 123"
match = re.search(r'\d\d\d', s)
match
<_sre.SRE_Match object; span=(13, 16), match='123'>
match.group()
'123'

В примере выше мы использовали шаблон \d\d\d. Шаблон \d в регулярных выражениях сравнивает единичные цифры, следовательно \d\d\d будет сравнивать цифры вида 111222786. Соответственно, цифры вида 121444 будут пропущены.

Основные шаблоны регулярных выражений

Символ Описание
. любой символ, за исключением новой строки
\w любой буквенный, цифровой символ, а также нижнее подчеркивание
\W любые не буквенные и не цифровые символы и не нижнее подчеркивание
\d любая одиночная цифра
\D любой одиночный символ, кроме цифры
\s любой пробельный символ, как например \n\t, а также сам пробел
\S любой не пробельный одиночный символ
[abc] любой одиночный символ в данном множестве, то есть в этом примере это либо  a, либо b, либо c
[^abc] любой одиночный символ, отличный от ab и c
[a-z] любой одиночный символ в диапазоне от a до z
[a-zA-Z] любой одиночный символ в диапазоне a-z или A-Z
[0-9] любой одиночный символ в диапазоне 09
^ сравнение начинается с начала строки
$ сравнение начинается с конца строки
+ один или больше символов (жадное соответствие).
* ноль или больше символов (жадное соответствие).

Рассмотрим еще один пример.

import re
s = "tim email is [email protected]"
match = re.search(r'[\w.-][email protected][\w.-]+', s)

# Приведенное выше регулярное выражение будет искать e-mail адрес

if match:
    print(match.group())
else:
    print("сравнений не обнаружено")
Ожидаемый результат
[email protected]

Здесь мы использовали шаблон [\w.-][email protected][\w.-]+ чтобы найти в строке соответствие с e-mail адресом. В случае успеха метод re.search() возвращает объект match, а уже при помощи метода этого объекта group() можно извлечь хранящийся там текст. В данном примере это [email protected]

Группровка выражений

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

match = re.search(r'([\w.-]+)@([\w.-]+)', s)

Обратите внимание: добавление скобок не означает изменение шаблона для поиска соответствия. Наш код по-прежнему ищет полное совпадение с заданным шаблоном. Если поиск увенчается успехом, match.group(1) будет соответствовать содержимому первых круглых скобок, а match.group(2) — содержимому вторых круглых скобок.

import re
s = "tim email is [email protected]"
match = re.search('([\w.-]+)@([\w.-]+)', s)
if match:
    print(match.group()) ## [email protected] (полное сравнение)
    print(match.group(1)) ## tim (the username, первая группа)
    print(match.group(2)) ## somehost (the host, вторая группа)

Функция findall()

Как вы уже знаете, функция re.search() находит только первое вхождение заданного шаблона в строку. А если мы хотим найти все вхождения, в дело вступает функция findall().

Синтаксис: findall(pattern, string, flags=0[optional])

В случае успеха данная функция возвращает список, в котором в виде строк содержатся все искомые вхождения по порядку. Если вхождений нет, то эта функция возвратит пустой список.

import re
s = "Tim's phone numbers are 12345-41521 and 78963-85214"
match = re.findall(r'\d{5}', s)

if match:
    print(match)
Ожидаемый результат:
['12345', '41521', '78963', '85214']

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

import re
s = "Tim's phone numbers are 12345-41521 and 78963-85214"
match = re.findall(r'(\d{5})-(\d{5})', s)
print(match)

for i in match:
    print()
    print(i)
    print("Первая группа", i[0])
    print("Вторая группа", i[1])
Ожидаемый результат:
[('12345', '41521'), ('78963', '85214')]

('12345', '41521')
Первая группа 12345
Вторая группа 41521

('78963', '85214')
Первая группа 78963
Вторая группа 85214

Опциональные флаги

Обе функции, re.search() и re.findall(), могут принимать необязательные параметры — флаги. С их помощью можно слегка изменять поведение функции.

Флаги Описание
re.IGNORECASE При поиске соответствий будет игнорироваться регистр символов.
re.DOTALL Позволяет (.) искать символ новой строки. По умолчанию (.) ищет любой символ кроме символа новой строки.
re.MULTILINE Благодаря этому флагу ^ и $ будут означать начало и конец каждой строчки (line) в многострочной строке (string). По умолчанию эти символы означают начало и конец строки (string).

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

Функция re.match() очень похожа на функцию re.search(). Различие состоит лишь в том, что функция re.match() начинает поиск сравнений с начала строки.

import re
s = "python tuts"
match = re.match(r'py', s)
match_1 = re.match(r'th', s)
if match:
    print(match.group()) # выведет на экран 'py'
if match_1:
    print(match_1.group()) # не выведет на экран ничего

Того же можно достичь и с функцией re.search(), просто добавив ^ к шаблону сравнения.

import re
s = "python tuts"
match = re.search(r'^py', s)
match_1 = re.search(r'^th', s)
if match:
    print(match.group()) # выведет на экран 'py'
if match_1:
    print(match_1.group()) # не выведет на экран ничего

На этом мы завершаем знакомство с модулем re языка Python.

Функция compile — Документация Python для сетевых инженеров 3.0

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

Использование компилированного выражения может ускорить обработку, и, как правило, такой вариант удобней использовать, так как в программе разделяется создание регулярного выражения и его использование. Кроме того, при использовании функции re.compile создается объект RegexObject, у которого есть несколько дополнительных возможностей, которых нет в объекте MatchObject.

Для компиляции регулярного выражения используется функция re.compile:

In [52]: regex = re.compile(r'\d+ +\S+ +\w+ +\S+')

Она возвращает объект RegexObject:

In [53]: regex
Out[53]: re.compile(r'\d+ +\S+ +\w+ +\S+', re.UNICODE)

У объекта RegexObject доступны такие методы и атрибуты:

In [55]: [method for method in dir(regex) if not method.startswith('_')]
Out[55]:
['findall',
 'finditer',
 'flags',
 'fullmatch',
 'groupindex',
 'groups',
 'match',
 'pattern',
 'scanner',
 'search',
 'split',
 'sub',
 'subn']

Обратите внимание, что у объекта Regex доступны методы search, match, finditer, findall. Это те же функции, которые доступны в модуле глобально, но теперь их надо применять к объекту.

Пример использования метода search:

In [67]: line = ' 100    a1b2.ac10.7000    DYNAMIC     Gi0/1'

In [68]: match = regex.search(line)

Теперь search надо вызывать как метод объекта regex. И передать как аргумент строку.

Результатом будет объект Match:

In [69]: match
Out[69]: <_sre.SRE_Match object; span=(1, 43), match='100    a1b2.ac10.7000    DYNAMIC     Gi0/1'>

In [70]: match.group()
Out[70]: '100    a1b2.ac10.7000    DYNAMIC     Gi0/1'

Пример компиляции регулярного выражения и его использования на примере разбора лог-файла (файл parse_log_compile.py):

import re

regex = re.compile(r'Host \S+ '
                   r'in vlan (\d+) '
                   r'is flapping between port '
                   r'(\S+) and port (\S+)')

ports = set()

with open('log.txt') as f:
    for m in regex.finditer(f.read()):
        vlan = m.group(1)
        ports.add(m.group(2))
        ports.add(m.group(3))

print('Петля между портами {} в VLAN {}'.format(', '.join(ports), vlan))

Это модифицированный пример с использованием finditer. Тут изменилось описание регулярного выражения:

regex = re.compile(r'Host \S+ '
                   r'in vlan (\d+) '
                   r'is flapping between port '
                   r'(\S+) and port (\S+)')

И вызов finditer теперь выполняется как метод объекта regex:

Регулярное выражение в Python с примерами | Комплект 1

Модуль Regular Expressions (RE) указывает набор строк (шаблон), который ему соответствует.
Чтобы понять аналогию RE, MetaCharacters полезны, важны и будут использоваться в функциях модуля re.
Всего имеется 14 метасимволов, и они будут обсуждаться по мере их выполнения в следующих функциях:

  • Функция compile ()
    Регулярные выражения компилируются в объекты шаблонов, которые имеют методы для различных операций, таких как поиск совпадений шаблонов или выполнение подстановок строк.

    import re

      

    p = re.compile('[a-e]')

      

    print(p.findall("Aye, said Mr. Gibenson Stark"))

    Выход:

    ['e', 'a', 'd', 'b', 'e', 'a']
    

    Понимание вывода:
    Первое вхождение — это «е» в «Да», а не «А», так как оно чувствительно к регистру.
    Следующее вхождение — «a» в «сказанном», затем «d» в «сказанном», затем «b» и «e» в «Гибенсоне», последний «а» соответствует «Старку».


    Metacharacter blackslash ‘/’ играет очень важную роль, поскольку сигнализирует о различных последовательностях. Если черный слеш должен использоваться без его специального значения в качестве метасимвола, используйте «//»

    \d   Matches any decimal digit, this is equivalent
         to the set class [0-9].
    \D   Matches any non-digit character.
    \s   Matches any whitespace character.
    \S   Matches any non-whitespace character
    \w   Matches any alphanumeric character, this is
         equivalent to the class [a-zA-Z0-9_].
    \W   Matches any non-alphanumeric character. 

    Заданный класс [/ s ,.] будет соответствовать любому символу пробела, ‘,’ или, ‘.’ ,

    import re

      

    p = re.compile('\d')

    print(p.findall("I went to him at 11 A.M. on 4th July 1886"))

      

    p = re.compile('\d+')

    print(p.findall("I went to him at 11 A.M. on 4th July 1886"))

    Выход:

    ['1', '1', '4', '1', '8', '8', '6']
    ['11', '4', '1886']
    

    import re

      

    p = re.compile('\w')

    print(p.findall("He said * in some_lang."))

      

    p = re.compile('\w+')

    print(p.findall("I went to him at 11 A.M., he said *** in some_language."))

      

    p = re.compile('\W')

    print(p.findall("he said *** in some_language."))

    Выход:

    ['H', 'e', 's', 'a', 'i', 'd', 'i', 'n', 's', 'o', 'm', 'e', '_', 'l', 'a', 'n', 'g']
    ['I', 'went', 'to', 'him', 'at', '11', 'A', 'M', 'he', 'said', 'in', 'some_language']
    [' ', ' ', '*', '*', '*', ' ', ' ', '.']
    

    import re

      

    p = re.compile('ab*')

    print(p.findall("ababbaabbb"))

    Выход:

    ['ab', 'abb', 'a', 'abbb']
    

    Понимание вывода:
    Наше RE — это ab *, который «a» сопровождается любым no. из ‘б’, начиная с 0.
    Вывод ‘ab’, действителен из-за одиночного ‘a’, сопровождаемого одиночным ‘b’.
    Вывод ‘abb’, действителен из-за одинарного ‘a’, сопровождаемого 2 ‘b’.
    Вывод ‘a’, допустим, потому что одиночный ‘a’ сопровождается 0 ‘b’.
    Вывод ‘abbb’, действителен из-за одного ‘a’, сопровождаемого 3 ‘b’.

  • Функция split ()
    Разбить строку по вхождению символа или шаблона, при нахождении этого шаблона оставшиеся символы из строки возвращаются как часть полученного списка.
    Синтаксис:
     re.split(pattern, string, maxsplit=0, flags=0)

    Первый параметр, pattern обозначает регулярное выражение, строка — это заданная строка, в которой будет производиться поиск шаблона и в которой происходит расщепление, maxsplit, если он не предоставлен, считается равным нулю ‘0’, и если предоставляется любое ненулевое значение, то Максимум, что происходит много расколов. Если maxsplit = 1, то строка будет разделена только один раз, что приведет к списку длины 2. Флаги очень полезны и могут помочь сократить код, они не являются необходимыми параметрами, например: flags = re.IGNORECASE, В этом разделении , случай будет проигнорирован.

    from re import split

      

    print(split('\W+', 'Words, words , Words'))

    print(split('\W+', "Word's words Words"))

      

    print(split('\W+', 'On 12th Jan 2016, at 11:02 AM'))

      

    print(split('\d+', 'On 12th Jan 2016, at 11:02 AM'))

    Выход:

    ['Words', 'words', 'Words']
    ['Word', 's', 'words', 'Words']
    ['On', '12th', 'Jan', '2016', 'at', '11', '02', 'AM']
    ['On ', 'th Jan ', ', at ', ':', ' AM']
    

    import re

      

    print(re.split('\d+', 'On 12th Jan 2016, at 11:02 AM', 1))

      

    print(re.split('[a-f]+', 'Aey, Boy oh boy, come here', flags = re.IGNORECASE))

    print(re.split('[a-f]+', 'Aey, Boy oh boy, come here'))

    Выход:

    ['On ', 'th Jan 2016, at 11:02 AM']
    ['', 'y, ', 'oy oh ', 'oy, ', 'om', ' h', 'r', '']
    ['A', 'y, Boy oh ', 'oy, ', 'om', ' h', 'r', '']
    
  • Функция sub ()
    Синтаксис:
     re.sub(pattern, repl, string, count=0, flags=0)

    ‘Sub’ в функции обозначает SubString, в заданной строке выполняется поиск определенного шаблона регулярного выражения (3-й параметр), и после нахождения шаблона подстроки заменяется на repl (2-й параметр), счетчик проверяет и поддерживает количество раз это происходит.

    import re

      

    print(re.sub('ub', '~*' , 'Subject has Uber booked already', flags = re.IGNORECASE))

      

    print(re.sub('ub', '~*' , 'Subject has Uber booked already'))

      

    print(re.sub('ub', '~*' , 'Subject has Uber booked already', count=1, flags = re.IGNORECASE))

      

    print(re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE))

    Выход

    S~*ject has ~*er booked already
    S~*ject has Uber booked already
    S~*ject has Uber booked already
    Baked Beans & Spam
    
  • Функция subn ()
    Синтаксис:
     re.subn(pattern, repl, string, count=0, flags=0)

    subn () во всех отношениях похожа на sub (), за исключением способа вывода. Он возвращает кортеж с общим количеством замен и новой строкой, а не просто строкой.

    import re

    print(re.subn('ub', '~*' , 'Subject has Uber booked already'))

    t = re.subn('ub', '~*' , 'Subject has Uber booked already', flags = re.IGNORECASE)

    print(t)

    print(len(t))

      

    print(t[0])

    Выход

    ('S~*ject has Uber booked already', 1)
    ('S~*ject has ~*er booked already', 2)
    Length of Tuple is:  2
    S~*ject has ~*er booked already
    
    
  • Функция escape ()
    Синтаксис:
    re.escape(string)

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

    import re

      

    print(re.escape("This is Awseome even 1 AM"))

    print(re.escape("I Asked what is this [a-9], he said \t ^WoW"))

    Выход

    This\ is\ Awseome\ even\ 1\ AM
    I\ Asked\ what\ is\ this\ \[a\-9\]\,\ he\ said\ \    \ \^WoW
    
  • Эта статья предоставлена Пиюшем Доорваром . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи [email protected] Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

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

    Про Python — Справочник — re (регулярные выражения)

    Инструменты для работы с регулярными выражениями.

    Регулярное выражение (re, regexp) позволяет описать некоторое множество строк при помощи шаблона для дальнейшего определения того, входит ли какая-либо строка в этом множество. Данный модуль предоставляет инструменты для работы с регулярными выражениями, подобные тем, которые можно обнаружить в языке Perl.

    Как шаблоны так и строки, по которым производится поиск, могут являться и строками Юникод (str) и 8-битными строками (bytes).

    Смешивать строки и байты не следует: нельзя сличить Юникод-строку с байтовым шаблоном и наоборот; при замене и строка, и шаблон, и заменитель должны быть одного типа.


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

    Дабы избежать необходимости экранирования, в качестве шаблонов регулярных выражений можно использовать сырые строки Питона (строки с префиксом r). Например: r'\n' — это строка из двух символов (\ и n), а '\n' — это строка из одного символа, обозначающего переход на новую строку. Шаблоны регулярных выражений в Питоне часто используют сырые строки.

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

    Попрактиковаться и отладить регулярные выражения можно на сайте https://regex101.com
    Существует сторонний модуль regex с совместимым программным интерфейсом, предлагающий расширенную функциональность и более совершенную поддержку Юникода.

    Синонимы поиска: re (регулярные выражения), regexp, регулярка, регулярки

    re.compile Компилирует объект регулярного выражения.для последующего использован…
    re.fullmatch Определяет соответствие строки указанному шаблону.
    re.match Ищет соответствие шаблону в начале строки.
    re.search Ищет соответствие шаблону в любом месте строки.
    Синтаксис регулярных выражений Здесь приводится базовая информация о синтаксисе регулярных выражений.

    re — Операции с регулярными выражениями — документация Python 3.8.5

    Исходный код: Lib / re.py


    Этот модуль обеспечивает операции сопоставления регулярных выражений, аналогичные те, что есть в Perl.

    И шаблоны, и строки для поиска могут быть строками Unicode ( str ) а также 8-битные строки ( байт ). Однако строки Unicode и 8-битные строки нельзя смешивать: то есть вы не можете сопоставить строку Unicode с шаблоном байтов или наоборот; аналогично, при запросе замены, замена строка должна быть того же типа, что и шаблон, и строка поиска.

    В регулярных выражениях используется обратная косая черта ( '\' ) для обозначения специальные формы или разрешить использование специальных символов без вызова их особое значение. Это противоречит использованию Python того же символ того же назначения в строковых литералах; например, чтобы соответствовать буквальная обратная косая черта, возможно, придется написать '\\\\' в качестве шаблона строка, потому что регулярное выражение должно быть \ , а каждое обратная косая черта должна быть выражена как \ внутри обычной строки Python буквальный.Также обратите внимание, что любые недопустимые escape-последовательности в Python использование обратной косой черты в строковых литералах теперь генерирует DeprecationWarning и в будущем это станет SyntaxError . Это поведение произойдет, даже если это допустимая escape-последовательность для регулярного выражения.

    Решение состоит в том, чтобы использовать нотацию строк Python для регулярных выражений. узоры; обратная косая черта не обрабатывается каким-либо особым образом в строковом литерале с префиксом 'r' .Итак, r "\ n" — это двухсимвольная строка, содержащая '\' и 'n' , а "\ n" — это односимвольная строка, содержащая новая линия. Обычно шаблоны выражаются в коде Python с использованием этого необработанного строковое обозначение.

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

    См. Также

    Сторонний модуль регулярных выражений, который имеет API, совместимый со стандартной библиотекой re module, но предлагает дополнительные функции и более полную поддержку Unicode.

    Синтаксис регулярного выражения

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

    Регулярные выражения могут быть объединены в новые регулярные выражения; если A и B являются регулярными выражениями, тогда AB также являются регулярными выражениями. В общем, если строка p соответствует A , а другая строка q соответствует B , строка pq будет соответствовать AB. Это справедливо, если только A или B не содержат низкий приоритет. операции; граничные условия между A и B ; или иметь пронумерованную группу Ссылки.Таким образом, сложные выражения можно легко построить из более простых примитивные выражения, подобные описанным здесь. Подробнее о теории и реализации регулярных выражений, обратитесь к книге Фридла [Frie09], или почти любой учебник по построению компиляторов.

    Далее следует краткое объяснение формата регулярных выражений. Для дальнейшего информацию и более мягкое изложение, обратитесь к Regular Expression HOWTO.

    Регулярные выражения могут содержать как специальные, так и обычные символы.Наиболее обычные символы, такие как 'A' , 'a' или '0' , являются простейшими обычными выражения; они просто соответствуют себе. Вы можете объединить обычные символов, поэтому последний соответствует строке 'последний' . (В остальном В разделе мы будем писать RE в этом специальном стиле , обычно без кавычек, и строки для сопоставления 'в одинарных кавычках' .)

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

    Квалификаторы повторения ( * , + , ? , {m, n} и т. Д.) Не могут быть непосредственно вложенные. Это позволяет избежать двусмысленности с суффиксом модификатора non-greedy ? и с другими модификаторами в других реализациях. Чтобы применить второй от повторения к внутреннему повторению можно использовать круглые скобки. Например, выражение (?: a {6}) * соответствует любому кратному шести 'a' символам.

    (Caret.) Соответствует началу строки, а также в режиме MULTILINE соответствует сразу после каждой новой строки.

    $

    Соответствует концу строки или непосредственно перед новой строкой в ​​конце строка, а в режиме MULTILINE также соответствует перед новой строкой. foo соответствует как «foo», так и «foobar», а регулярное выражение foo $ соответствует только «фу». Что еще более интересно, поиск foo. долларов в 'foo1 \ nfoo2 \ n' обычно совпадает с «foo2», но с «foo1» в режиме MULTILINE ; поиск один $ в 'foo \ n' найдет два (пустых) совпадения: одно непосредственно перед перевод строки и один в конце строки.

    *

    Заставляет результирующий RE соответствовать 0 или более повторениям предыдущего RE, как как можно больше повторений. ab * будет соответствовать «a», «ab» или «a», за которыми следует на любое количество знаков «б».

    +

    Заставляет результирующий RE соответствовать одному или нескольким повторениям предыдущего RE. ab + будет соответствовать «a», за которым следует любое ненулевое число «b»; Я не буду совпадать просто «а».

    ?

    Заставляет результирующий RE соответствовать 0 или 1 повторениям предыдущего RE. ab? будет соответствовать либо «a», либо «ab».

    *? , +? , ??

    Значения '*' , '+' и '?' Квалификаторы все жадные ; они совпадают как можно больше текста.Иногда такое поведение нежелательно; если здесь <. *> сопоставляется с ' b ' , он будет соответствовать всему строка, а не только '' . Добавление ? после того, как квалификатор делает это выполнить сопоставление в нежадном или минимальном моде ; как несколько символы будут сопоставлены по мере возможности. Использование RE <. *?> будет соответствовать только '' .

    {m}

    Указывает, что должно быть сопоставлено ровно m копий предыдущего RE; меньше совпадения приводят к несоответствию всего RE.Например, {6} будет соответствовать ровно шесть 'a' символов, но не пять.

    {m, n}

    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например, a {3,5} будет соответствовать от 3 до 5 'a' символов. Опуская м указывает нижняя граница равна нулю, а отсутствие n указывает бесконечную верхнюю границу.Как Например, a {4,} b будет соответствовать 'aaaab' или тысяче 'a' символов за которым следует 'b' , но не 'aaab' . Запятая не может быть опущена или модификатор можно спутать с ранее описанной формой.

    {м, п}?

    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно более несколько повторений.Это нежадная версия предыдущего квалификатора. Например, на 6-символьная строка 'aaaaaa' , a {3,5} будет соответствовать 5 'a' символам, а а {3,5}? будет соответствовать только 3 символам.

    \

    Either экранирует специальные символы (позволяя вам сопоставлять такие символы, как '*' , '?' и т. Д.) Или сигнализирует особую последовательность; специальный последовательности обсуждаются ниже.

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

    .

    7.2. re — Операции с регулярными выражениями — документация Python 2.7.18

    Этот модуль предоставляет операции сопоставления регулярных выражений, аналогичные те, что есть в Perl. И шаблоны, и строки для поиска могут быть Строки Unicode, а также 8-битные строки.

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

    Решение состоит в том, чтобы использовать нотацию исходных строк Python для регулярных выражений. узоры; обратная косая черта не обрабатывается каким-либо особым образом в строковом литерале с префиксом 'r' . Итак, r "\ n" — это двухсимвольная строка, содержащая '\' и 'n' , а "\ n" — это односимвольная строка, содержащая новая линия. Обычно шаблоны выражаются в коде Python с использованием этого необработанного строковое обозначение.

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

    7.2.1. Синтаксис регулярного выражения

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

    Регулярные выражения могут быть объединены в новые регулярные выражения; если A и B являются регулярными выражениями, тогда AB также являются регулярными выражениями.В общем, если строка p соответствует A , а другая строка q соответствует B , строка pq будет соответствовать AB. Это справедливо, если только A или B не содержат низкий приоритет. операции; граничные условия между A и B ; или иметь пронумерованную группу Ссылки. Таким образом, сложные выражения можно легко построить из более простых примитивные выражения, подобные описанным здесь. Подробнее о теории и реализации регулярных выражений, обратитесь к упомянутой книге Фридла выше, или почти любой учебник по построению компиляторов.

    Далее следует краткое объяснение формата регулярных выражений. Для дальнейшего информацию и более мягкое изложение, обратитесь к Regular Expression HOWTO.

    Регулярные выражения могут содержать как специальные, так и обычные символы. Наиболее обычные символы, такие как 'A' , 'a' или '0' , являются простейшими обычными выражения; они просто соответствуют себе. Вы можете объединить обычные символов, поэтому last соответствует строке 'last' .(В остальном RE в , этот специальный стиль , обычно без кавычек, и строки для сопоставления 'в одинарных кавычках' .)

    Некоторые символы, например '|' или '(' , являются специальными. Специальные персонажи либо обозначают классы обычных персонажей, либо влияют как интерпретируются окружающие их регулярные выражения. Обычный строки шаблона выражения не могут содержать нулевые байты, но могут указывать нулевой байт в нотации \ number , e.г., '\ x00' .

    Квалификаторы повторения ( * , + , ? , {m, n} и т. Д.) Не могут быть непосредственно вложенные. Это позволяет избежать двусмысленности с суффиксом модификатора non-greedy ? , и с другими модификаторами в других реализациях. Чтобы применить второй от повторения к внутреннему повторению можно использовать круглые скобки. Например, выражение (?: a {6}) * соответствует любому кратному шести 'a' символам.

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

    '.'

    (Caret.) Соответствует началу строки, а также в режиме MULTILINE соответствует сразу после каждой новой строки.

    '$'

    Соответствует концу строки или непосредственно перед новой строкой в ​​конце строка, а в режиме MULTILINE также соответствует перед новой строкой. foo соответствует как «foo», так и «foobar», а регулярное выражение foo $ соответствует только «фу». Что еще интереснее, поиск foo. долларов из 'foo1 \ nfoo2 \ n' обычно совпадает с «foo2», но с «foo1» в режиме MULTILINE ; поиск один $ в 'foo \ n' найдет два (пустых) совпадения: одно непосредственно перед перевод строки и один в конце строки.

    '*'

    Заставляет результирующий RE соответствовать 0 или более повторениям предыдущего RE, как как можно больше повторений. ab * будет соответствовать «a», «ab» или «a», за которыми следует на любое количество знаков «б».

    '+'

    Заставляет результирующий RE соответствовать 1 или нескольким повторениям предыдущего RE. ab + будет соответствовать «a», за которым следует любое ненулевое число «b»; Я не буду совпадать просто «а».

    '?'

    Заставляет результирующий RE соответствовать 0 или 1 повторениям предыдущего RE. ab? будет соответствовать либо «a», либо «ab».

    *? , +? , ??

    '*' , '+' и '?' квалификаторов все жадные ; они совпадают как можно больше текста.Иногда такое поведение нежелательно; если здесь <. *> сопоставляется с b , он будет соответствовать всему строка, а не только . Добавление ? после прохождения квалификации выполнить сопоставление в моде нежадный или минимальный ; как несколько символы будут сопоставлены по мере возможности. При использовании RE <. *?> будет соответствовать только .

    {m}

    Указывает, что должно быть сопоставлено ровно m копий предыдущего RE; меньше совпадения приводят к несоответствию всего RE.Например, {6} будет соответствовать ровно шесть 'а' знаков, но не пять.

    {m, n}

    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например, a {3,5} будет соответствовать от 3 до 5 a символов. Опуская м указывает нижняя граница равна нулю, а отсутствие n указывает бесконечную верхнюю границу.Как Например, a {4,} b будет соответствовать aaaab или тысяче 'a' символов за которым следует b , но не aaab . Запятая не может быть опущена или модификатор можно спутать с ранее описанной формой.

    {м, п}?

    Вызывает совпадение результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно более несколько повторений.Это нежадная версия предыдущего квалификатора. Например, на 6-символьная строка 'aaaaaa' , a {3,5} будет соответствовать 5 'a' символов, а а {3,5}? будет соответствовать только 3 символам.

    '\'

    Либо экранирует специальные символы (что позволяет сопоставлять символы вроде '*' , '?' и т. Д.) Или сигнализирует особую последовательность; специальный последовательности обсуждаются ниже.

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

    []

    Используется для обозначения набора символов. В наборе:

    • Символы могут быть перечислены индивидуально, например [amk] будет соответствовать 'a' , м или к .

    • Диапазоны символов могут быть обозначены двумя символами и разделением для них '-' , например [a-z] будет соответствовать любой строчной букве ASCII, [0-5] [0-9] будет соответствовать всем двузначным числам от 00 до 59 , и [0-9A-Fa-f] соответствует любой шестнадцатеричной цифре.Если - экранировано (например, [a \ -z] ), или если он указан как первый или последний символ (например,

    .

    6.2. re — Операции с регулярными выражениями — документация Python 3.4.10

    Этот модуль обеспечивает операции сопоставления регулярных выражений, аналогичные те, что есть в Perl.

    И шаблоны, и строки для поиска могут быть строками Unicode, а также 8-битные строки. Однако строки Unicode и 8-битные строки нельзя смешивать: то есть вы не можете сопоставить строку Unicode с шаблоном байтов или наоборот; аналогично, при запросе замены, замена строка должна быть того же типа, что и шаблон, и строка поиска.

    Регулярные выражения используют символ обратной косой черты (‘\’) для обозначения специальные формы или разрешить использование специальных символов без вызова их особое значение. Это противоречит использованию Python того же символ того же назначения в строковых литералах; например, чтобы соответствовать буквальная обратная косая черта, возможно, придется написать ‘\\\\’ в качестве шаблона строка, потому что регулярное выражение должно быть \\, и каждый обратная косая черта должна быть выражена как \\ внутри обычной строки Python буквальный.

    Решение состоит в том, чтобы использовать нотацию строк Python для регулярных выражений. узоры; обратная косая черта не обрабатывается каким-либо особым образом в строковом литерале с префиксом «r».Итак, r «\ n» — это двухсимвольная строка, содержащая ‘\’ и ‘n’, а «\ n» — это односимвольная строка, содержащая новая линия. Обычно шаблоны выражаются в коде Python с использованием этого необработанного строковое обозначение.

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

    6.2.1. Синтаксис регулярного выражения

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

    Регулярные выражения могут быть объединены в новые регулярные выражения; если A и B, являются регулярными выражениями, тогда AB также являются регулярными выражениями.В общем, если строка p соответствует A , а другая строка q соответствует B , строка pq будет соответствовать AB. Это справедливо, если только A или B не содержат низкий приоритет. операции; граничные условия между A и B ; или иметь пронумерованную группу Ссылки. Таким образом, сложные выражения можно легко построить из более простых примитивные выражения, подобные описанным здесь. Подробнее о теории и реализации регулярных выражений, обратитесь к упомянутой книге Фридла выше, или почти любой учебник по построению компиляторов.

    Далее следует краткое объяснение формата регулярных выражений. Для дальнейшего Для получения дополнительной информации и более мягкого изложения обратитесь к Regular Expression HOWTO .

    Регулярные выражения могут содержать как специальные, так и обычные символы. Наиболее обычные символы, такие как ‘A’, ‘a’ или ‘0’, являются простейшими обычными выражения; они просто соответствуют себе. Вы можете объединить обычные символов, поэтому последний соответствует строке «последний». (В остальном в разделе RE мы будем писать RE в этом особом стиле, обычно без кавычек, и строки, которые нужно сопоставить, заключены в одинарные кавычки.)

    Некоторые символы, например ‘|’ или «(«, особенные. Особые персонажи либо обозначают классы обычных персонажей, либо влияют как интерпретируются окружающие их регулярные выражения. Обычный строки шаблона выражения не могут содержать нулевые байты, но могут указывать нулевой байт с использованием нотации \ number, такой как ‘\ x00’.

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

    ‘.’
    (точка) В режиме по умолчанию это соответствует любому символу, кроме новой строки. Если указан флаг DOTALL, соответствует любому символу включая новую строку.’
    (Caret.) Соответствует началу строки, и в режиме MULTILINE также соответствует сразу после каждой новой строки.
    $
    Соответствует концу строки или непосредственно перед новой строкой в ​​конце строка, а в режиме MULTILINE также соответствует перед новой строкой. фу соответствует как «foo», так и «foobar», а регулярное выражение foo $ соответствует только «фу». Что еще интереснее, поиск foo. $ В ‘foo1 \ nfoo2 \ n’ обычно совпадает с «foo2», но с «foo1» в многопоточном режиме; поиск один $ в ‘foo \ n’ найдет два (пустых) совпадения: одно непосредственно перед перевод строки и один в конце строки.
    ‘*’
    Заставляет результирующий RE соответствовать 0 или более повторениям предыдущего RE, как как можно больше повторений. ab * будет соответствовать «a», «ab» или «a», за которым следует на любое количество знаков «б».
    ‘+’
    Заставляет результирующий RE соответствовать 1 или нескольким повторениям предыдущего RE. ab + будет соответствовать «a», за которым следует любое ненулевое количество «b»; Я не буду совпадать просто «а».
    ‘?’
    Заставляет результирующий RE соответствовать 0 или 1 повторению предыдущего RE.ab? будет соответствовать либо «a», либо «ab».
    * ?, + ?, ??
    Знаки «*», «+» и «?» квалификаторы все жадные ; они совпадают как можно больше текста. Иногда такое поведение нежелательно; если здесь <. *> сопоставляется с ‘

    title

    ‘, он будет соответствовать всему строка, а не только ‘

    ‘. Добавление ‘?’ после того, как квалификатор сделает это выполнить сопоставление в моде нежадный или минимальный ; как несколько символы будут сопоставлены по мере возможности.С помощью .*? в предыдущем выражение будет соответствовать только ‘

    ‘.

    {m}
    Указывает, что должно быть сопоставлено ровно м копий предыдущего RE; меньше совпадения приводят к несоответствию всего RE. Например, {6} будет соответствовать ровно шесть знаков «а», но не пять.
    {m, n}
    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например, {3,5} соответствует от 3 до 5 символов «a».Опуская м. указывает нижняя граница равна нулю, а отсутствие n задает бесконечную верхнюю границу. Как Например, a {4,} b будет соответствовать aaaab или тысяче символов ‘a’ с последующим b, но не aaab. Запятая не может быть опущена или модификатор можно спутать с ранее описанной формой.
    {м, п}?
    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно более несколько повторений.Это нежадная версия предыдущего квалификатора. Например, на 6-символьная строка ‘aaaaaa’, {3,5} будет соответствовать 5 символам ‘a’, а {3,5}? будет соответствовать только 3 символам.
    ‘\’

    Либо экранирует специальные символы (позволяя вам сопоставлять символы вроде ‘*’, ‘?’ и т. д.) или сигнализирует о специальной последовательности; специальный последовательности обсуждаются ниже.

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

    []

    Используется для обозначения набора символов. В наборе:

    • Символы могут быть перечислены по отдельности, например [amk] будет соответствовать «a», «м» или «к».
    • Диапазоны символов могут быть обозначены двумя символами и разделением их через ‘-‘, например [a-z] будет соответствовать любой строчной букве ASCII, [0-5] [0-9] будет соответствовать всем двузначным числам от 00 до 59, а [0-9A-Fa-f] соответствует любой шестнадцатеричной цифре.Если — экранируется (например, [a \ -z]) или если он помещен в качестве первого или последнего символа (например, [a-]), он будет соответствовать буквальному ‘-‘.
    • Специальные символы теряют свое особое значение внутри наборов. Например, [(+ *)] будет соответствовать любому из буквальных символов ‘(‘, ‘+’, ‘*’, или ‘)’.
    • Также принимаются классы символов, такие как \ w или \ S (определенные ниже). внутри набора, хотя символы, которые они соответствуют, зависит от того, Действует режим ASCII или LOCALE.
    • Символы, которые не входят в диапазон, могут быть сопоставлены , дополняющим набор.не имеет особого значения, если это не первый символ в набор.
    • Чтобы соответствовать литералу ‘]’ внутри набора, поставьте перед ним обратную косую черту или поместите его в начало набора. Например, и [() [\] {}], и [] () [{}] будут соответствовать круглой скобке.
    ‘|’
    A | B, где A и B могут быть произвольными RE, создает регулярное выражение, которое будет соответствовать либо A, либо B. Произвольное количество RE может быть разделено ‘|’ в этом случае.
    .

    6.2. re — Операции с регулярными выражениями — документация Python v3.2.6

    Этот модуль обеспечивает операции сопоставления регулярных выражений, аналогичные те, что есть в Perl.

    И шаблоны, и строки для поиска могут быть строками Unicode, а также 8-битные строки. Однако строки Unicode и 8-битные строки нельзя смешивать: то есть вы не можете сопоставить строку Unicode с шаблоном байтов или наоборот; аналогично, при запросе замены, замена строка должна быть того же типа, что и шаблон, и строка поиска.

    Регулярные выражения используют символ обратной косой черты (‘\’) для обозначения специальные формы или разрешить использование специальных символов без вызова их особое значение. Это противоречит использованию Python того же символ того же назначения в строковых литералах; например, чтобы соответствовать буквальная обратная косая черта, возможно, придется написать ‘\\\\’ в качестве шаблона строка, потому что регулярное выражение должно быть \\, и каждый обратная косая черта должна быть выражена как \\ внутри обычной строки Python буквальный.

    Решение состоит в том, чтобы использовать нотацию строк Python для регулярных выражений. узоры; обратная косая черта не обрабатывается каким-либо особым образом в строковом литерале с префиксом «r».Итак, r «\ n» — это двухсимвольная строка, содержащая ‘\’ и ‘n’, а «\ n» — это односимвольная строка, содержащая новая линия. Обычно шаблоны выражаются в коде Python с использованием этого необработанного строковое обозначение.

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

    См. Также

    Освоение регулярных выражений
    Книга Джеффри Фридла по регулярным выражениям, изданная O’Reilly. В второе издание книги больше не охватывает Python, но первое Издание очень подробно рассматривало написание хороших шаблонов регулярных выражений.

    6.2.1. Синтаксис регулярного выражения

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

    Регулярные выражения могут быть объединены в новые регулярные выражения; если A и B, являются регулярными выражениями, тогда AB также являются регулярными выражениями. В общем, если строка p соответствует A , а другая строка q соответствует B , строка pq будет соответствовать AB. Это справедливо, если только A или B не содержат низкий приоритет. операции; граничные условия между A и B ; или иметь пронумерованную группу Ссылки.Таким образом, сложные выражения можно легко построить из более простых примитивные выражения, подобные описанным здесь. Подробнее о теории и реализации регулярных выражений, обратитесь к упомянутой книге Фридла выше, или почти любой учебник по построению компиляторов.

    Далее следует краткое объяснение формата регулярных выражений. Для дальнейшего Для получения дополнительной информации и более мягкого изложения обратитесь к Regular Expression HOWTO .

    Регулярные выражения могут содержать как специальные, так и обычные символы.Наиболее обычные символы, такие как ‘A’, ‘a’ или ‘0’, являются простейшими обычными выражения; они просто соответствуют себе. Вы можете объединить обычные символов, поэтому последний соответствует строке «последний». (В остальном в разделе RE мы будем писать RE в этом особом стиле, обычно без кавычек, и строки, которые нужно сопоставить, заключены в одинарные кавычки.)

    Некоторые символы, например ‘|’ или «(«, особенные. Особые персонажи либо обозначают классы обычных персонажей, либо влияют как интерпретируются окружающие их регулярные выражения.’

    (Caret.) Соответствует началу строки, а также в режиме MULTILINE. соответствует сразу после каждой новой строки.
    $
    Соответствует концу строки или непосредственно перед новой строкой в ​​конце строка, а в режиме MULTILINE также соответствует перед новой строкой. фу соответствует как «foo», так и «foobar», а регулярное выражение foo $ соответствует только «фу». Что еще интереснее, поиск foo. $ В ‘foo1 \ nfoo2 \ n’ обычно совпадает с «foo2», но с «foo1» в многопоточном режиме; поиск один $ в ‘foo \ n’ найдет два (пустых) совпадения: одно непосредственно перед перевод строки и один в конце строки.
    ‘*’
    Заставляет результирующий RE соответствовать 0 или более повторениям предыдущего RE, как как можно больше повторений. ab * будет соответствовать «a», «ab» или «a», за которым следует на любое количество знаков «б».
    ‘+’
    Заставляет результирующий RE соответствовать 1 или нескольким повторениям предыдущего RE. ab + будет соответствовать «a», за которым следует любое ненулевое количество «b»; Я не буду совпадать просто «а».
    ‘?’
    Заставляет результирующий RE соответствовать 0 или 1 повторению предыдущего RE.ab? будет соответствовать либо «a», либо «ab».
    * ?, + ?, ??
    Символы «*», «+» и «?» квалификаторы все жадные ; они совпадают как можно больше текста. Иногда такое поведение нежелательно; если здесь <. *> сопоставляется с ‘

    title

    ‘, он будет соответствовать всему строка, а не только ‘

    ‘. Добавление ‘?’ после того, как квалификатор сделает это выполнить сопоставление в моде нежадный или минимальный ; как несколько символы будут сопоставлены по мере возможности.С помощью .*? в предыдущем выражение будет соответствовать только ‘

    ‘.

    {м}
    Указывает, что должно быть сопоставлено ровно м копий предыдущего RE; меньше совпадения приводят к несоответствию всего RE. Например, {6} будет соответствовать ровно шесть знаков «а», но не пять.
    {m, n}
    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например, {3,5} соответствует от 3 до 5 символов «a».Опуская м. указывает нижняя граница равна нулю, а отсутствие n задает бесконечную верхнюю границу. Как Например, a {4,} b будет соответствовать aaaab или тысяче символов ‘a’ с последующим b, но не aaab. Запятая не может быть опущена или модификатор можно спутать с ранее описанной формой.
    {м, п}?
    Приводит к совпадению результирующего RE от m до n повторений предыдущего RE, пытаясь сопоставить как можно более несколько повторений.Это нежадная версия предыдущего квалификатора. Например, на 6-символьная строка ‘aaaaaa’, {3,5} будет соответствовать 5 символам ‘a’, а {3,5}? будет соответствовать только 3 символам.
    ‘\’

    Либо экранирует специальные символы (позволяя вам сопоставлять символы вроде ‘*’, ‘?’ и т. д.) или сигнализирует о специальной последовательности; специальный последовательности обсуждаются ниже.

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

    []

    Используется для обозначения набора символов. В наборе:

    • Символы могут быть перечислены по отдельности, например [amk] будет соответствовать «a», «м» или «к».
    • Диапазоны символов могут быть обозначены двумя символами и разделением их через ‘-‘, например [a-z] будет соответствовать любой строчной букве ASCII, [0-5] [0-9] будет соответствовать всем двузначным числам от 00 до 59, а [0-9A-Fa-f] соответствует любой шестнадцатеричной цифре.Если — экранируется (например, [a \ -z]) или если он помещен в качестве первого или последнего символа (например, [a-]), он будет соответствовать буквальному ‘-‘.
    • Специальные символы теряют свое особое значение внутри наборов. Например, [(+ *)] будет соответствовать любому из буквальных символов ‘(‘, ‘+’, ‘*’, или ‘)’.
    • Также принимаются классы символов, такие как \ w или \ S (определенные ниже). внутри набора, хотя символы, которые они соответствуют, зависит от того, Действует режим ASCII или LOCALE.
    • Символы, которые не входят в диапазон, могут быть сопоставлены , дополняющим набор.не имеет особого значения, если это не первый символ в набор.
    • Чтобы соответствовать литералу ‘]’ внутри набора, поставьте перед ним обратную косую черту или поместите его в начало набора. Например, и [() [\] {}], и [] () [{}] будут соответствовать круглой скобке.
    ‘|’
    A | B, где A и B могут быть произвольными RE, создает регулярное выражение, которое будет соответствовать либо A, либо B. Произвольное количество RE может быть разделено
    .