re
— Операции с регулярными выражениями в Python3.7Этот модуль предоставляет возможность использования регулярных выражений похожих на те, которые имеют широкое распространение в языке Perl.
И шаблоны и строки использующиеся как данные для сопоставления или поиска МОГУТ быть как Unicode строками (str
), так и 8-битными строками (последовательностями байт bytes
). Следует отметить, что Unicode строки и 8-битовые строки не могут использоваться совместно: вы не можете осуществлять сопоставление Unicode шаблона и bytes
строки и наоборот. Похожая ситуация и в случае с подстановкой/заменой: заменяемая строка обязана быть того же самого типа, что и шаблон и исходная строка.
Регулярные выражения используют символ обратного слэша ( бэкслэша/обратной косой черты '\'
) для указания на специальные формы или для предоставления возможности использования специальных символов без обращения к их особому значению. Это противоречит обычному использованию в Python этих же символов в подобном назначении в обычных строковых литералах. К примеру, для сопоставления с строковым значением обратного слэша придётся использовать '\\\\'
как строкового шаблона, потому что регулярное выражение должно быть \\
и всякий обратный слэш обязан быть выражен как \\
внутри регулярного строкового литерала в Python.
Решение подобной проблемы в использовании сырых строк для шаблонов регулярных выражений в Python. Обратные слэши не обрабатываются особым образом в строковых литералах, предваряемые символом 'r'
. Так, 'r"\n"'
двухсимволльная строка содержащая '\'
и 'n'
, в то время, как обычная запись "\n"
это односимвольная строка содержащая символ “перевода строки”. Обычно шаблоны выражаются в виде сырых строк в Python.
Важным замечанием является то, что большинство регулярных выражений доступны как функции и методы уровня модуля исполнения для скомпилированных регулярных выражений. Такие функции являются ссылками, которые с одной стороны не требуют от вас предварительной компиляции регулярного объекта, а с другой вы упускаете некоторые возможности применения параметров для тонкой настройки.
Обратите внимание на модуль regex
, который предоставляет API совместимое с re
модулем, но предлагает дополнительную функциональность и более ориентирован на поддержку Unicode.
Регулярные выражения могут быть сконкатенированы (последовательно объединены) для получения новых регулярных выражений; если %%A%% и %%B%% оба являются регулярными выражениями, то %%AB%% также является регулярным выражением. В общем, если строка %%p%% сопоставляется с %%A%%, а другая строка %%q%% соответствует %%B%%, строка %%pq%% будет соответствовать %%AB%%. Это верно до тех пор, пока %%A%% или %%B%% содержат операции с низким приоритетом; граничные условия между %%А%% и %%В%%; или пронумерованные групповые ссылки. Если это так, то сложные выражения могут быть легко построены из более простых примитивных выражений, подобных описанным здесь. За подробностями теории и реализации регулярных выражений обращайтесь к книге Фридла [Frie09] или почти к любому учебнику об архитектуре построения компилятора.
Регулярные выражения могут содержать как обычные так и специальные символы. Большинство обычных символов, таких как 'A'
, 'a'
, '0'
и т.д., являются простейшими регулярными выражениями: они соответствуют сами себе. Вы можете сконкатенировать обычные символы. Так, last
соответствует строке 'last'
. Чтобы устранить путаницу, мы будем записывать регулярные выражения без кавычек
, а строки для сопоставления с кавычками, например, 'вот строка для сопоставления'
.
.
^
$
foo
совпадает как с 'foo'
, так и с 'foobar'
, а регулярное выражение foo$
соответствует только 'foo'
.
foo.$
в 'foo1\nfoo2\n'
будет успешно сопоставлен с 'foo2'
. Но в режиме MULTILINE ему также будет сопоставлен и 'foo1'
. поиск же $
в 'foo\n'
найдет два (пустых) совпадения: одно непосредственно перед новой строкой, а другое - в конце всей строки.
*
ab*
состоит из конкатенированных a
+ b*
. Поэтому, такому выражению будет соответствовать такие строки: 'a'
, 'ab'
, 'abb'
и 'abbbb'
или другими словами, 'a'
с любым количеством следующих за ним 'b'
.
+
ab+
будет сопоставляться с любой строкой, состоящей из 'ab'
+ любое количество символов 'b'
. Например, 'ab'
, 'abbb'
, 'abbbbbb'
, 'abbbbbbb'
и так далее.
?
ab?
будет соответствовать ТОЛЬКО строкам 'a'
или 'ab'
и больше никаким.
*?
, +?
, ??
'*'
, '+'
, '?'
квалифицируются как жадные (greedy). Они соответствуют такому количеству текста, которое только возможно. Порой такое поведение нежелательно. Например, выражение <.*>
будет применяться относительно '<a> b <c>'
, то соответствовать оно будет всей строке, а не только '<a>'
. Добавление ?
меняет поведение, заставляя сопоставляться на “не жадный” или “минимальный” манер. В данном случае, лучше всего проиллюстрировать примером:
>>> import re
>>> p = re.compile('<.*?>')
>>> p.findall('<a> b <c>')
['<a>', '<c>']
>>> p.match('<a> b <c>')
<_sre.SRE_Match object; span=(0, 3), match='<a>'>
{m}
, где %%m%% — целое число
a{3}
будет успешно сопоставлено с 'aaa'
, 'aaaa'
, 'aaaaaaa'
, но не будет с 'aa'
.
{m,n}
, где %%m%% и %%n%% — целые числа
a{3,5}
будет соответствовать любой строке, состоящей от 3 до 5 символов 'a'
('aaa'
, 'aaaa'
, 'aaaaa'
). Можно избежать указания верхней и нижней границы. Так, отсутствие %%m%% подразумевает 0, а %%n%% — бесконечность как верхнюю границу. Так, например, a{2,}b
будет соответствовать 'aab'
или 'aaaaaaaaaab'
, но не будет соответствовать 'ab'
. Обратите внимание, что запятая не может быть исключена, потому что произойдёт смешивание с предыдущей описанной выше формой.
{m,n}?
, где %%m%% и %%n%% — целые числа
'aaaaaa'
, a{3,5}
будет соотвествовать 5 символам 'a'
, в то время как a{3,5}?
будет соответствовать лишь трём таким символам.
\
'*'
или '?'
, например) или сигнализирует о специальной последовательности. Эта функциональность будет рассмотрена ниже.
[]
Используется для выражения набора символов. В таком наборе:
[folk]
будет соответствовать 'f'
, 'k'
, 'l'
, 'o'
.
Диапазоны символов могут быть определены разделением двух граничных символов символом '-'
, например:
'[a-z]'
— строчные сивмолы английского алфавита по таблице символов ASCII.
[0-5][0-9]
— будут соответствовать двузначному номеру от 00
до 59
,
[0-9A-Fa-f]
— будет соответствовать символам, использующимся для составления шестнадцатеричного числа
если символ '-'
'экранирован (например, '[a\-v]'
) ИЛИ используется как первый или последний символ (например, '[b-]'
, '[-v]'
), то он обозначает не диапазон, а отдельный символ '-'
[(+*)]
будут обозначать любой из литералов, обозначающих символы '('
, ')'
, '+'
, '*'
,
\w
или \S
(будет разьяснено ниже) также принимаются внутри наборов, а значение этих классов определяется от режима (ASCII или LOCALE) принудительно,
'^'
(не путать с отдельным использованием этого символа без границ набора []
). Так, например, использование [^5]
будет соответствать ЛЮБОМУ символу, кроме '5'
. А [^^]
, будет соответствовать любому символу, кроме '^'
. ВНИМАНИЕ! ^
не имеет никакого специального значения, если используется НЕ ПЕРВЫМ символом в наборе.
Сопоставление со специальным символом ']'
внутри набора, предполагает ЛИБО экранирование его обратным слэшем, либо помещением первым символом в набор. Так, оба выражения: [()[]]
и []()[]
обозначают одно и тоже: использование любых типов скобок,
Поддержка вложенных наборов и наборов операций как в Unicode Technical Standard #18 может быть добавлена в будущем. Это может существенно изменить синтаксис, поэтому для содействия этим изменениям был добавлен FutureWarning
(Исключительная ситуация), которое возбуждается, в ситуациях неоднозначного толкования в ряде случаев. Такие ситуации, это наборы, стартующие с [
или содержащие символьные последовательности '--'
, '&&'
, '~~'
и '||'
. Чтобы избежать это исключение экранируйте их в обратные слэши
|
A|B
в которых и A
и B
могут быть произвольными регулярными выражениями, создаёт такое регулярное выражение, которое будет соответствовать или A
или B
. Количество произвольных конкатенаций выражений может быть любым, в качестве разделителей всегда используется |
. Подобный синтаксис может использоваться и внутри групп. Когда целевая строка сканируется, регулярные выражения, разделённые символом |
проверяются на сопоставление слева направо. Когда первый из шаблонов сопоставляется, вся ветка принимается и обработка завершается. Это обозначает, что если A
сработал, то B
больше не вызывается. Другими словами, |
никогда не бывает жадным. Для сопоставления с символом '|'
следует его экранировать.
(...)
, где ...
любое регулярное выражение
\number
, описанной ниже.
(?...)
?
следующее за (
, в противном случае не имеет смысла). Первый символ в '?'
определяется значение и дальнейший синтаксис всей конструкции. Такое расширение обычно не создаёт новую группу.
(?P<name>...)
— исключение из общего правила. Следующие ниже примеры иллюстрируют возможное использование:
(?aiLmsux)
'a'
, 'i'
, 'L'
, 'm'
, 's'
, 'u'
, 'x'
, Группа может быть и пустым множеством. Каждый символ обозначает соответствующий флаг для всего высказывания:
Включение флагов как часть регулярного выражения вместо передачи их в вызов re.compile()
это довольно удобная практика. Заметим, что флаги должны передаваться первыми в строке.
(?:...)
Незахватывающая версия регулярного выражения. Сопоставляется с каким угодно регулярным рыражением внутри скобок, однако подстрока, сопоставленная группой НЕ МОЖЕТ быть извлечена и использована для сопоставления позже в шаблоне.
(?aiLmsux-imsx:)
'a'
, 'i'
, 'L'
, 'm'
, 's'
, 'u'
, 'x'
, опционально следующего за ним символа '-'
с последующим ОДНИМ или более символами из набора 'i'
, 'm'
, 's'
, 'x'
. Каждый символ УСТАНАВЛИВАЕТ или УДАЛЯЕТ (если следует за '-'
) соответствующий флаг для всего высказывания:
'a'
, 'L'
и 'u'
являются взаимно исключающими, когда используются как inline флаги, поэтому они не могут сочетаться или следовать за '-'
. Напротив, если один из этих символов появляется в inline группе, это переопределяет режим сопоставления во всей включённой группы. В Unicode шаблоны (?a:...)
переключается на сопоставление только с ASCII, а (?u:...)
переключает режим в Unicode сопоставление (по умолчанию). В байтовых шаблонах (для байтовых строк/последовательностей) (?L%...)
переключает для зависящий от текущей локали режим сопоставления, а (a?...)
переключает в режим ASCII (по умолчанию).
В Python 3.7
Символы 'a'
, 'L'
, 'u'
также могут использоваться в группах
(?P<name>...)
(?P<quote>['"]).*?(?P=quote)
— то есть на основании соответствия строки, заключённой в одинарные или двойные кавычки:
Контект ссылки на группу “quote” | Способ сослаться |
---|---|
В том же самом шаблоне | (?P=quote) — как в примере \1 |
Когда происходит обработка объекта %%m%% | m.group('quote') m.end('quote') (etc.) |
В строке, переданной аргументу repl re.sub() | \q<quote> \q<1> \1 |
(?P=name)
(?#...)
(?=...)
if ... сопоставить следующее
, но не включает само условие в качестве результата сопоставления. Это называется УПРЕЖДАЮЩЕЕ УТВЕРЖДЕНИЕ. К примеру, Isaac (?=Asimov)
будет сопоставлен с 'Isaac '
только в том случае, если за ним следует Asimov
(?!...)
if ... NOT следующее
. Это негативное упреждающее утверждение. К примеру, Isaac (?!Asimov)
будет сопоставлен только с Isaac
только если следует НЕ будет Asimov
.
(?<=...)
...
которое заканчивается на текущей позиции. Это называется позитивным упреждающим утверждением.
(?<=abc)def
будет соответствовать abcdef
, поскольку конструкция позитивного упреждающего утверждения создаст буфер на 3 символа и проверит, соответствует ли ей содержащийся шаблон. Контейнер подобного типа ОБЯЗАН содержать только строки фиксированной длинны. Это означает, что abcd
или a|b
разрешены, но конструкции с переменным числом символов — НЕТ (такие, как a*
или a{3,4}
).
search()
вместо match()
:
>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'
(?<!...)
...
. Называется это негативным упреждающим утверждением. Как и в позитивном упреждающем утверждении, содержащийся шаблон может состоять только из строк фиксированной длинны. Шаблоны, которые начинаются с негативного упреждающего утверждения МОГУТ соответствовать началу строки, по которой осуществляется поиск.
(?(id/name)yes-pattern|no-pattern)
yes-pattern
если существует группа с соответствующим id или name и с no-pattern
в противном случае. no-pattern
опциональный и может не указываться.
(<)?(\w+@\w+(?:.\w+)+)(?(1)>|$)
паттерн на проверку ошибок в e-mail адресе. Он будет соответстовать <user@host.com>
также, как и user@host.com
, но не будет работать с user@host.com>
.
Спецсимволы, содержат '\'
и следующий за ним символ из списка, приведённого ниже.
\number
(.+) \1
соответствует 'tu tu'
или '5 5'
, но НЕ СООТВЕТСТВУЕТ'tuktuk'
или '66'
(обратите внимание на значащий пробел). Эта специальная служебная последовательность, которая позволяет производить сопоставление только с 99 группами.
'['
и ']'
) символьного класса, все числовые экранирования распознаются как символы.
\A
\b
\b
определяется как ГРАНИЦЫ СЛОВА (boundary) между \w
и \W
символом (и так далее) или между \w
и началом или окончанием строки. Слово определяется как последовательность печатных символов.
r'\bfoo\b'
соответствует 'foo'
, 'foo.'
, '(foo)'
, 'bar foo baz'
, но не соответствует 'foobar'
или 'foo3'
.
\b
представляется как “возврат каретки” (backspace) символ, в целях совместимости со строковыми литералами Python.
\B
r'pyth\B'
будет соответствовать 'python'
, 'pyth3'
, но не будет 'pyth'
, 'pyth.'
или 'pyth!'
. '\B'
по поведению является противоположностью '\b'
, поэтому ограничения на Unicode поведение и границы слова в LOCALE аналогичны.
'\d'
[0-9]
, а также кучу других цифровых символов. Если выставлен ASCII флаг, то используется ТОЛЬКО [0-9]
.
[0-9]
.
'\D'
'\d'
. В ASCII это соответствует высказыванию [^0-9]
.
'\s'
[ \t\n\r\f\v]
) и множество других символов. К примеру, неразрывные типографские пробелы, существующие в наборах для различных языков. Для ASCII строк включает только [ \t\n\r\f\v]
.
'\S'
[^ \t\n\r\f\v]
). Для ASCII строк включает только [^ \t\n\r\f\v]
.
'\w'
[a-zA-Z0-9_]
.
[a-zA-Z0-9_]
. Если флаг LOCALE установлен, соответствует буквенно-цифровым символам текущей локали + символ подчёркивания.
'\W'
'\w'
. В ASCII соответствует [^a-zA-Z0-9_]
. Соответственно, если используется флаг LOCALE, то используется сопоставление с текущей локалью.
'\Z'
Большинство стандартных экранирований поддерживаемым строковыми литералами Python также поддерживаются парсером регулярных выражений:
\a \b \f \n
\r \t \u \U
\v \x \
Обратите внимание, что \b
используется для представления границ слова, и обозначает “возврат каретки” только внутри символьных классов.
'\u'
и '\U'
имеют смысл только внутри Unicode шаблона. В байтовых шаблонах это ошибка. Неопределённые экранирования символов в ASCII зарезервированы на будущее и интерпретируются как ошибки.