re — Операции с регулярными выражениями
Исходный код: Lib/re/
Этот модуль предоставляет операции сопоставления регулярных выражений, аналогичные тем, которые встречаются в Perl.
И шаблоны, и строки, которые подлежат поиску, могут быть строками Unicode (str) а также строками 8-битных значений (bytes). Однако строки Unicode и строки 8-битных значений не могут смешиваться: то есть вы не можете сопоставить строку Unicode с шаблоном bytes или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон и строка поиска.
В регулярных выражениях символ обратной косой черты ('\') используется для обозначения специальных форм или для разрешения использования специальных символов без вызова их специального значения. Это вступает в конфликт с использованием Python того же символа для той же цели в строковых литералах; например, чтобы сопоставить литеру обратной косой черты, нужно написать '\\\\' в качестве строки шаблона, поскольку регулярное выражение должно быть \\, а каждая обратная косая черта должна быть выражена как \\ внутри обычной строки Python. Также обратите внимание, что любые недопустимые последовательности экранирования в использовании Python обратной косой черты в строковых литералах теперь генерируют SyntaxWarning, а в будущем это станет SyntaxError. Это поведение будет происходить даже если это допустимая последовательность экранирования для регулярного выражения.
Решение заключается в использовании синтаксиса «сырых строк» Python для шаблонов регулярных выражений; обратные косые черты не обрабатываются каким-либо специальным образом в строковом литерале с префиксом 'r'. Таким образом, r"\n" — это строка из двух символов, содержащая '\' и 'n', а "\n" — это строка из одного символа, содержащая символ новой строки. Обычно шаблоны выражаются в коде Python с использованием этого синтаксиса «сырых строк».
Важно отметить, что большинство операций с регулярными выражениями доступны как функции на уровне модуля и методы для скомпилированных регулярных выражений. Функции являются сокращениями, которые не требуют предварительной компиляции объекта regex, но пропускают некоторые параметры тонкой настройки.
См. также
Модуль сторонней разработки regex, который имеет API, совместимый с модулем стандартной библиотеки re, но предлагает дополнительные функции и более полную поддержку Unicode.
Синтаксис регулярных выражений
Регулярное выражение (или RE) задаёт множество строк, которые ему соответствуют; функции в этом модуле позволяют проверить, соответствует ли определённая строка заданному регулярному выражению (или если заданное регулярное выражение соответствует определённой строке, что сводится к тому же самому).
Регулярные выражения можно конкатенировать, чтобы сформировать новые регулярные выражения; если A и B — оба регулярные выражения, то AB также является регулярным выражением. В общем случае, если строка p соответствует A, а другая строка q соответствует B, то строка pq будет соответствовать AB. Это верно, если A или B не содержат операций с низким приоритетом; граничные условия между A и B; или имеют ссылки на группы с номерами. Таким образом, сложные выражения легко можно построить из более простых основных выражений, описанных здесь. Для получения подробной информации о теории и реализации регулярных выражений обратитесь к книге Фридла [Frie09] или почти любой учебной книге по построению компиляторов.
Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более понятного изложения обратитесь к Руководству по регулярным выражениям.
Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, таких как 'A', 'a', или '0', являются простейшими регулярными выражениями; они просто соответствуют самим себе. Вы можете конкатенировать обычные символы, поэтому last соответствует строке 'last'. (В остальной части этого раздела мы будем писать RE в this special style, обычно без кавычек, а строки, которые нужно сопоставить, 'in single quotes'.)
Некоторые символы, такие как '|' или '(', являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на то, как интерпретируются окружающие их регулярные выражения.
Операторы повторения или квантификаторы (*, +, ?, {m,n}, и т.д.) не могут быть непосредственно вложены. Это предотвращает неоднозначность с суффиксом модификатора нежадного соответствия ?, и с другими модификаторами в других реализациях. Для применения второго повторения к внутреннему повторению могут использоваться скобки. Например, выражение (?:a{6})* соответствует любому кратному шести 'a' символам.
Специальные символы:
-
. -
(Точка.) В стандартном режиме это соответствует любому символу, кроме новой строки. Если указан флаг
DOTALL, это соответствует любому символу, включая новую строку.(?s:.)соответствует любому символу независимо от флагов.
-
^ -
(Знак возведения в степень.) Соответствует началу строки, а в режиме
MULTILINEтакже соответствует сразу после каждой новой строки.
-
$ -
Соответствует концу строки или непосредственно перед новой строкой в конце строки, а в режиме
MULTILINEтакже соответствует перед новой строкой.fooсоответствует как ‘foo’, так и ‘foobar’, в то время как регулярное выражениеfoo$соответствует только ‘foo’. Более интересно, поискfoo.$в'foo1\nfoo2\n'соответствует ‘foo2’ в обычном режиме, а ‘foo1’ в режимеMULTILINE; поиск одного$в'foo\n'найдёт два (пустых) соответствия: одно непосредственно перед новой строкой и одно в конце строки.
-
* -
Заставляет результирующее RE соответствовать 0 или более повторений предшествующего RE, как можно больше повторений.
ab*будет соответствовать ‘a’, ‘ab’ или ‘a’, после которого следует любое количество ‘b’.
-
+ -
Заставляет результирующее RE соответствовать 1 или более повторений предшествующего RE.
ab+будет соответствовать ‘a’, после которого следует любое ненулевое количество ‘b’s; оно не будет соответствовать только ‘a’.
-
? -
Заставляет результирующее RE соответствовать 0 или 1 повторению предшествующего RE.
ab?будет соответствовать либо ‘a’, либо ‘ab’.
-
*?, +?, ?? -
Квантификаторы
'*','+', и'?'являются жадными; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если RE<.*>сопоставляется со строкой'<a> b <c>', оно будет соответствовать всей строке, а не только'<a>'. Добавление?после квантификатора заставляет его выполнять соответствие в нежадном или минимальном режиме; будет соответствовать как можно меньше символов. Используя RE<.*?>будет соответствовать только'<a>'.
-
*+, ++, ?+ -
Подобно квантификаторам
'*','+', и'?', те, где'+'добавлен, также соответствуют как можно большему количеству раз. Однако, в отличие от истинных жадных квантификаторов, они не допускают обратной проверки, когда выражение, следующее за ним, не может быть сопоставлено. Эти известны как поглощающие квантификаторы. Например,a*aбудет соответствовать'aaaa', потому чтоa*будет соответствовать всем 4'a's, но, когда встречается конечный'a', выражение перепроверяется, так что в итогеa*соответствует 3'a's всего, и четвёртый'a'соответствует конечному'a'. Однако, когдаa*+aиспользуется для соответствия'aaaa',a*+будет соответствовать всем 4'a', но когда конечный'a'не сможет найти больше символов для соответствия, выражение не может быть перепроверено и, следовательно, не сможет соответствовать.x*+,x++иx?+эквивалентны(?>x*),(?>x+)и(?>x?)соответственно.Добавлен в версии 3.11.
-
{m} -
Указывает, что должно быть сопоставлено ровно m копий предыдущего RE; меньше соответствий приводят к тому, что все RE не соответствуют. Например,
a{6}будет соответствовать ровно шести'a'символам, но не пяти. -
{m,n} -
Заставляет результирующее RE соответствовать от m до n повторений предшествующего RE, пытаясь сопоставить как можно больше повторений. Например,
a{3,5}будет соответствовать от 3 до 5'a'символов. Пропуск m указывает нижнюю границу 0, а пропуск n указывает бесконечную верхнюю границу. В качестве примера,a{4,}bбудет соответствовать'aaaab'или тысяче'a'символам, после которых следует'b', но не'aaab'. Запятую нельзя опустить, иначе модификатор будет смешиваться с ранее описанной формой. -
{m,n}? -
Заставляет результирующее RE соответствовать от m до n повторений предшествующего RE, пытаясь сопоставить как можно меньше повторений. Это нежадная версия предыдущего квантификатора. Например, в строке из 6 символов
'aaaaaa',a{3,5}будет соответствовать 5'a'символам, тогда какa{3,5}?будет соответствовать только 3 символам. -
{m,n}+ -
Заставляет результирующее RE соответствовать от m до n повторений предшествующего RE, пытаясь сопоставить как можно больше повторений, не создавая никаких точек обратной проверки. Это поглощающая версия вышеуказанного квантификатора. Например, в строке из 6 символов
'aaaaaa',a{3,5}+aaпытается сопоставить 5'a'символов, затем, требуя ещё 2'a's, потребует больше символов, чем доступно, и, следовательно, потерпит неудачу, в то время какa{3,5}aaбудет соответствоватьa{3,5}захватит 5, затем 4'a's путём обратной проверки, а затем конечные 2'a's будут соответствовать конечномуaaв шаблоне.x{m,n}+эквивалентно(?>x{m,n}).Добавлен в версии 3.11.
-
\ -
Либо экранирует специальные символы (позволяя вам сопоставить символы, такие как
'*','?', и так далее), либо сигнализирует о специальной последовательности; специальные последовательности обсуждаются ниже.Если вы не используете строку ссылок для выражения шаблона, помните, что Python также использует обратную косую черту в качестве последовательности экранирования в строковых литералах; если последовательность экранирования не распознаётся анализатором Python, обратная косая черта и последующий символ включаются в результирующую строку. Однако, если Python распознает полученную последовательность, обратная косая черта должна быть повторена дважды. Это сложно и трудно понять, поэтому настоятельно рекомендуется использовать строки ссылок для всех, кроме самых простых выражений.
-
[] -
Используется для указания набора символов. В наборе:
- Символы могут быть перечислены индивидуально, например
[amk]будет соответствовать'a','m', или'k'.
- Диапазоны символов могут быть указаны, задав два символа и разделив их
'-', например[a-z]будет соответствовать любой строчной букве ASCII,[0-5][0-9]будет соответствовать всем двузначным числам от00до59, а[0-9A-Fa-f]будет соответствовать любой шестнадцатеричной цифре. Если-экранирована (например,[a\-z]) или если она размещена в качестве первого или последнего символа (например,[-a]или[a-]), она будет соответствовать буквальному'-'. - Специальные символы теряют свой специальный смысл внутри наборов. Например,
[(+*)]будет соответствовать любому из буквальных символов'(','+','*', или')'.
- Классы символов, такие как
\wили\S(определены ниже), также принимаются внутри набора, хотя символы, которым они соответствуют, зависят от используемых флагов.
- Символам, которые не входят в диапазон, можно соответствовать, дополняя набор. Если первый символ набора —
'^', всем символам, которые не входят в набор, будет соответствовать. Например,[^5]будет соответствовать любому символу, кроме'5', а[^^]будет соответствовать любому символу, кроме'^'.^не имеет специального значения, если это не первый символ в наборе. - Для соответствия буквальному
']'внутри набора нужно предварять его обратной косой чертой или помещать его в начало набора. Например, оба[()[\]{}]и[]()[{}]будут соответствовать правой скобке, а также левой скобке, фигурным скобкам и круглым скобкам.
- Поддержка вложенных наборов и операций над наборами, как в Unicode Technical Standard #18, может быть добавлена в будущем. Это изменит синтаксис, поэтому для облегчения этой смены в неоднозначных случаях будет подниматься
FutureWarning. Это включает наборы, начинающиеся с буквального'['или содержащие буквальные последовательности символов'--','&&','~~', и'||'. Чтобы избежать предупреждения, экранируйте их обратной косой чертой.
Изменено в версии 3.7:
FutureWarningподнимается, если набор символов содержит конструкции, которые изменят семантику в будущем. - Символы могут быть перечислены индивидуально, например
-
| -
A|B, где A и B могут быть произвольными регулярными выражениями, создаёт регулярное выражение, которое будет соответствовать либо A, либо B. Произвольное количество регулярных выражений может быть разделено'|'таким образом. Это также может быть использовано внутри групп (см. ниже). При сканировании целевой строки регулярные выражения, разделённые'|', пытаются соответствовать слева направо. Когда один шаблон полностью соответствует, эта ветвь принимается. Это означает, что как только A соответствует, B больше не будет тестироваться, даже если бы это привело к более длинному соответствию в целом. Другими словами, оператор'|'никогда не является жадным. Для соответствия буквальному'|'используйте\|, или заключите его в набор символов, как в[|].
-
(...) -
Соответствует любому регулярному выражению, которое находится внутри круглых скобок, и указывает начало и конец группы; содержимое группы может быть получено после выполнения соответствия и может быть сопоставлено позже в строке с помощью
\numberспециальной последовательности, описанной ниже. Для соответствия буквальным'('или')'используйте\(или\), или заключите их в набор символов:[(],[)].
-
(?...) -
Это обозначение расширения (a
'?'после'('не имеет смысла иначе). Первый символ после'?'определяет смысл и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу;(?P<name>...)— единственное исключение из этого правила. Ниже приведены текущие поддерживаемые расширения. -
(?aiLmsux) -
(Одна или несколько букв из набора
'a','i','L','m','s','u','x'.) Группа соответствует пустой строке; буквы устанавливают соответствующие флаги для всего регулярного выражения:-
re.A(только соответствие ASCII) -
re.I(без учёта регистра) -
re.L(зависимо от локали) -
re.M(многострочное) -
re.S(точка соответствует всем) -
re.U(соответствие Unicode) -
re.X(развёрнутый)
(Флаги описаны в Содержимое модуля.) Это полезно, если вы хотите включить флаги как часть регулярного выражения вместо передачи аргумента флага функции
re.compile(). Флаги должны использоваться вначале в строке выражения.Изменено в версии 3.11: Это конструкция может быть использована только в начале выражения.
-
-
(?:...) -
Незахватывающая версия круглых скобок. Сопоставляет любое регулярное выражение внутри скобок, но подстрока, соответствующая группе, не может быть получена после выполнения соответствия или сослана позже в шаблоне.
-
(?aiLmsux-imsx:...) -
(Ноль или более букв из набора
'a','i','L','m','s','u','x', необязательно после'-'за которым следует одна или несколько букв из набора'i','m','s','x'.) Буквы устанавливают или снимают соответствующие флаги для части выражения:-
re.A(только соответствие ASCII) -
re.I(без учёта регистра) -
re.L(зависимо от локали) -
re.M(многострочное) -
re.S(точка соответствует всем) -
re.U(соответствие Unicode) -
re.X(развёрнутый)
(Флаги описаны в Содержимое модуля.)
Буквы
'a','L'и'u'взаимно исключают друг друга при использовании в качестве флагов в строке, поэтому их нельзя объединять или следовать за'-'. Вместо этого, когда один из них появляется в строке, он переопределяет режим соответствия во включающей группе. В Unicode-шаблонах(?a:...)переключается на соответствие только ASCII, а(?u:...)переключается на соответствие Unicode (по умолчанию). В шаблонах байтов(?L:...)переключается на соответствие, зависящее от локали, а(?a:...)переключается на соответствие только ASCII (по умолчанию). Это переопределение действует только для узкой строки, а исходный режим соответствия восстанавливается за пределами строки.Добавлена в версии 3.6.
Изменено в версии 3.7: Буквы
'a','L'и'u'также могут быть использованы в группе. -
-
(?>...) -
Пытается сопоставить
...как если бы это было отдельное регулярное выражение, а при успехе продолжает сопоставлять остальную часть шаблона после него. Если последующий шаблон не соответствует, стек может быть восстановлен только до точки до(?>...), потому что после выхода выражение, известное как атомная группа, отбрасывает все точки стека внутри себя. Таким образом,(?>.*).никогда не будет соответствовать чему-либо, потому что сначала.*будет соответствовать всем возможным символам, а затем, не имея ничего оставшегося для соответствия, окончательное.не сможет сопоставиться. Поскольку в атомной группе нет сохранённых точек стека и нет точки стека до неё, всё выражение не будет соответствовать.Добавлена в версии 3.11.
-
(?P<name>...) -
Аналогично обычным круглым скобкам, но подстрока, соответствующая группе, доступна через символическое имя группы name. Имена групп должны быть допустимыми идентификаторами Python, а в шаблонах
bytesони могут содержать только байты в диапазоне ASCII. Каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является пронумерованной группой, как если бы группа не имела имени.Именованные группы могут быть использованы в трёх контекстах. Если шаблон
(?P<quote>['"]).*?(?P=quote)(т. е. соответствует строке, заключённой в одинарные или двойные кавычки):Контекст ссылки на группу “quote”
Способы ссылки на неё
в самом шаблоне
-
(?P=quote)(как показано) \1
при обработке объекта совпадения m
m.group('quote')-
m.end('quote')(и т. д.)
в строке, переданной в аргумент repl функции
re.sub()\g<quote>\g<1>\1
Изменено в версии 3.12: В шаблонах
bytesимя группы name может содержать только байты в диапазоне ASCII (b'\x00'-b'\x7f'). -
-
(?P=name) -
Ссылка на именованную группу; она соответствует той же текстовой последовательности, что и ранее соответствующая группа с именем name.
-
(?#...) -
Комментарий; содержимое скобок просто игнорируется.
-
(?=...) -
Соответствует, если
...соответствует дальше, но не потребляет никакой части строки. Это называется утверждением предвосхищения. Например,Isaac (?=Asimov)будет соответствовать'Isaac 'только в том случае, если за ним следует'Asimov'.
-
(?!...) -
Соответствует, если
...не соответствует дальше. Это утверждение отрицательного предвосхищения. Например,Isaac (?!Asimov)будет соответствовать'Isaac 'только в том случае, если за ним не следует'Asimov'.
-
(?<=...) -
Соответствует, если текущее положение в строке предшествует совпадению с
..., которое заканчивается в текущем положении. Это называется утверждением положительного обратного просмотра.(?<=abc)defнайдёт совпадение в'abcdef', так как обратный просмотр вернётся на 3 символа назад и проверит, соответствует ли содержащийся шаблон. Содержащийся шаблон должен соответствовать строкам фиксированной длины, что означает, чтоabcилиa|bдопустимы, ноa*иa{3,4}— нет. Обратите внимание, что шаблоны, которые начинаются с утверждений положительного обратного просмотра, не будут соответствовать началу искомой строки; вы, скорее всего, захотите использовать функциюsearch(), а не функциюmatch():>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'Этот пример ищет слово, следующее за дефисом:
>>> m = re.search(r'(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'
Изменено в версии 3.5: Добавлена поддержка ссылок на группы фиксированной длины.
-
(?<!...) -
Соответствует, если в текущей позиции строки не предшествует совпадение с
.... Это называется утверждением отрицательного обратного просмотра. Подобно утверждениям положительного обратного просмотра, содержащийся шаблон должен соответствовать строкам фиксированной длины. Шаблоны, которые начинаются с утверждений отрицательного обратного просмотра, могут соответствовать началу искомой строки.
-
(?(id/name)yes-pattern|no-pattern) -
Попытается сопоставить с
yes-pattern, если группа с заданным id или name существует, и сno-pattern, если нет.no-patternнеобязательно и может быть опущено. Например,(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)— плохой шаблон для поиска электронных писем, который будет соответствовать'<user@host.com>'и'user@host.com', но не'<user@host.com'ни'user@host.com>'.Изменено в версии 3.12: Группа id может содержать только ASCII цифры. В шаблонах
bytesимя группы name может содержать только байты в диапазоне ASCII (b'\x00'-b'\x7f').
Специальные последовательности состоят из '\' и символа из следующего списка. Если обычный символ не является ASCII цифрой или ASCII буквой, то результирующее регулярное выражение будет соответствовать второму символу. Например, \$ соответствует символу '$'.
-
\number -
Соответствует содержимому группы с тем же номером. Группы нумеруются, начиная с 1. Например,
(.+) \1соответствует'the the'или'55 55', но не'thethe'(обратите внимание на пробел после группы). Эта специальная последовательность может использоваться только для соответствия одной из первых 99 групп. Если первая цифра number равна 0 или number имеет длину 3 восьмеричных цифр, она не будет интерпретироваться как совпадение с группой, а как символ с восьмеричным значением number. Внутри'['и']'класса символов все числовые экранирования рассматриваются как символы.
-
\A -
Соответствует только в начале строки.
-
\b -
Соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность символов слова. Обратите внимание, что формально
\bопределяется как граница между\wи\Wсимволом (или наоборот), или между\wи началом или концом строки. Это означает, чтоr'\bat\b'соответствует'at','at.','(at)', и'as at ay'но не'attempt'или'atlas'.По умолчанию символами слова в шаблонах Unicode (str) являются Unicode буквенно-цифровые символы и символ подчёркивания, но это можно изменить, используя флаг
ASCII. Границы слов определяются текущим языковым стандартом, если используется флагLOCALE.Примечание
Внутри диапазона символов
\bпредставляет символ ввода, для совместимости с строковыми литералами Python.
-
\B -
Соответствует пустой строке, но только тогда, когда она не находится в начале или конце слова. Это означает, что
r'at\B'соответствует'athens','atom','attorney', но не'at','at.', или'at!'.\B— противоположность\b, поэтому символы слова в шаблонах Unicode (str) — Unicode буквенно-цифровые символы или символ подчёркивания, хотя это можно изменить с помощью флагаASCII. Границы слов определяются текущим языковым стандартом, если используется флагLOCALE.Примечание
Обратите внимание, что
\Bне соответствует пустой строке, что отличается от реализаций регулярных выражений в других языках программирования, таких как Perl. Это поведение сохраняется для совместимости.
-
\d -
- Для шаблонов Unicode (str):
-
Соответствует любой десятичной цифре Unicode (то есть любому символу в категории символов Unicode [Nd]). Это включает
[0-9], а также многие другие цифры.Соответствует
[0-9]при использовании флагаASCII. - Для шаблонов 8-битных (bytes):
-
Соответствует любой десятичной цифре в наборе символов ASCII; это эквивалентно
[0-9].
-
\D -
Соответствует любому символу, который не является десятичной цифрой. Это противоположность
\d.Соответствует
[^0-9]при использовании флагаASCII.
-
\s -
- Для шаблонов Unicode (str):
-
Соответствует Unicode символам пробела (как определено функцией
str.isspace()). Это включает[ \t\n\r\f\v], а также многие другие символы, например, неразрывные пробелы, предписанные правилами типографики во многих языках.Соответствует
[ \t\n\r\f\v]при использовании флагаASCII. - Для шаблонов 8-битных (bytes):
-
Соответствует символам, считающимся пробелами в наборе символов ASCII; это эквивалентно
[ \t\n\r\f\v].
-
\S -
Соответствует любому символу, который не является символом пробела. Это противоположность
\s.Соответствует
[^ \t\n\r\f\v]при использовании флагаASCII.
-
\w -
- Для шаблонов Unicode (str):
-
Совпадает с символами Unicode-слов; это включает все Unicode-буквенно-цифровые символы (как определено в
str.isalnum()), а также символ подчёркивания (_).Совпадает с
[a-zA-Z0-9_]при использовании флагаASCII. - Для шаблонов 8-битных (bytes):
-
Совпадает с символами, считающимися буквенно-цифровыми в наборе символов ASCII; это эквивалентно
[a-zA-Z0-9_]. Если используется флагLOCALE, совпадают символы, считающиеся буквенно-цифровыми в текущем языковом стандарте, и символ подчёркивания.
-
\W -
Совпадает с любым символом, который не является символом слова. Это противоположность
\w. По умолчанию совпадают символы, не являющиеся подчёркиваниями (_), для которыхstr.isalnum()возвращаетFalse.Совпадает с
[^a-zA-Z0-9_]при использовании флагаASCII.Если используется флаг
LOCALE, совпадают символы, которые не являются буквенно-цифровыми в текущем языковом стандарте, и символом подчёркивания.
-
\Z -
Совпадает только в конце строки.
Большинство последовательностей экранирования, поддерживаемых строками Python, также принимаются парсером регулярных выражений:
\a \b \f \n \N \r \t \u \U \v \x \\
(Обратите внимание, что \b используется для представления границ слов и означает «ввод» только внутри символьных классов.)
'\u', '\U', и '\N' последовательности экранирования распознаются только в шаблонах Unicode (str). В шаблонах bytes они являются ошибками. Неизвестные ASCII-символьные последовательности экранирования зарезервированы для будущего использования и обрабатываются как ошибки.
Восьмеричные последовательности экранирования включаются в ограниченной форме. Если первая цифра равна 0, или если есть три восьмеричные цифры, она считается восьмеричной последовательностью экранирования. В противном случае это ссылка на группу. Как и для строковых литералов, восьмеричные последовательности экранирования всегда имеют длину не более трех цифр.
Изменено в версии 3.3: Добавлены последовательности экранирования '\u' и '\U'.
Изменено в версии 3.6: Неизвестные последовательности экранирования, состоящие из '\' и буквы ASCII, теперь являются ошибками.
Изменено в версии 3.8: Добавлена последовательность экранирования '\N{name}'. Как и в строковых литералах, она расширяется до указанного символа Unicode (например, '\N{EM DASH}').
Содержание модуля
Модуль определяет несколько функций, констант и исключение. Некоторые функции представляют собой упрощенные версии полнофункциональных методов для скомпилированных регулярных выражений. Большинство нетривиальных приложений всегда используют скомпилированную форму.
Флаги
Изменено в версии 3.6: Константы флагов теперь являются экземплярами RegexFlag, которые являются подклассом enum.IntFlag.
-
class re.RegexFlag -
Класс
enum.IntFlag, содержащий параметры регулярных выражений, перечисленные ниже.Добавлен в версии 3.11: - добавлен в
__all__
-
re.A -
re.ASCII -
Принудительно использовать сопоставление только с ASCII-символами вместо полного сопоставления с Юникодом для
\w,\W,\b,\B,\d,\D,\sи\S. Это имеет смысл только для шаблонов Юникода (str), и игнорируется для шаблонов типа bytes.Соответствует встроенному флагу
(?a).
-
re.DEBUG -
Отображает отладочную информацию о скомпилированном выражении.
Нет соответствующего встроенного флага.
-
re.I -
re.IGNORECASE -
Выполняет регистронезависимое сопоставление; выражения, такие как
[A-Z], также будут совпадать с прописными буквами. Полное сопоставление с Юникодом (например,Üсопоставление сü) также работает, если не используется флагASCIIдля отключения сопоставлений с не-ASCII-символами. Текущий локали не влияет на действие этого флага, если не используется также флагLOCALE.Соответствует встроенному флагу
(?i).Обратите внимание, что когда шаблоны Юникода
[a-z]или[A-Z]используются в сочетании с флагомIGNORECASE, они будут сопоставляться с 52 буквами ASCII и 4 дополнительными символами Юникода: ‘İ’ (U+0130, заглавная буква I с точкой сверху), ‘ı’ (U+0131, строчная буква i без точки), ‘ſ’ (U+017F, строчная буква long s) и ‘K’ (U+212A, знак Кельвина). Если используется флагASCII, будут сопоставляться только буквы от ‘a’ до ‘z’ и от ‘A’ до ‘Z’.
-
re.L -
re.LOCALE -
Принудительно использовать сопоставление
\w,\W,\b,\Bи регистронезависимое сопоставление, зависящие от текущей локали. Этот флаг может быть использован только с шаблонами типа bytes.Соответствует встроенному флагу
(?L).Предупреждение
Этот флаг не рекомендуется; рассмотрите использование сопоставления с Юникодом вместо него. Механизм локали очень ненадежен, так как он обрабатывает только одну «культуру» за раз и работает только с 8-битными локалями. Сопоставление с Юникодом включено по умолчанию для шаблонов Юникода (str) и может обрабатывать различные локали и языки.
Изменено в версии 3.6:
LOCALEможет быть использован только с шаблонами типа bytes и несовместим сASCII.Изменено в версии 3.7: Объекты скомпилированных регулярных выражений с флагом
LOCALEбольше не зависят от локали во время компиляции. Только локаль во время сопоставления влияет на результат.
-
re.M -
re.MULTILINE -
При указании символ
'^'сопоставляется в начале строки и в начале каждой строки (непосредственно после каждой новой строки); и символ'$'сопоставляется в конце строки и в конце каждой строки (непосредственно перед каждой новой строкой). По умолчанию'^'сопоставляется только в начале строки, а'$'только в конце строки и непосредственно перед новой строкой (если таковая имеется) в конце строки.Соответствует встроенному флагу
(?m).
-
re.NOFLAG -
Указывает на отсутствие примененных флагов, значение равно
0. Этот флаг может быть использован в качестве значения по умолчанию для аргумента ключевого слова функции или как базовое значение, которое будет условно объединено с другими флагами. Пример использования в качестве значения по умолчанию:def myfunc(text, flag=re.NOFLAG): return re.match(text, flag)Добавлен в версии 3.11.
-
re.S -
re.DOTALL -
Принудительно сделать специальный символ
'.'сопоставляемым с любым символом, включая символ новой строки; без этого флага'.'будет сопоставляться со всем, *кроме* новой строки.Соответствует встроенному флагу
(?s).
-
re.U -
re.UNICODE -
В Python 3 символы Юникода сопоставляются по умолчанию для шаблонов
str. Этот флаг, следовательно, избыточен и не оказывает никакого влияния, и он сохраняется только для обратной совместимости.См.
ASCII, чтобы ограничить сопоставление символами ASCII вместо этого.
-
re.X -
re.VERBOSE -
Этот флаг позволяет писать более удобочитаемые регулярные выражения, позволяя визуально разделять логические части шаблона и добавлять комментарии. Пробелы в шаблоне игнорируются, за исключением случаев, когда они находятся в классе символов или предваряются неэкранированным обратным слэшем, или внутри токенов, таких как
*?,(?:или(?P<...>. Например,(? :и* ?не допускаются. Когда строка содержит#, которая не находится в классе символов и не предваряется неэкранированным обратным слэшем, все символы слева от такого#до конца строки игнорируются.Это означает, что следующие два объекта регулярных выражений, которые соответствуют десятичному числу, функционально эквивалентны:
a = re.compile(r"""\d + # the integral part \. # the decimal point \d * # some fractional digits""", re.X) b = re.compile(r"\d+\.\d*")Соответствует встроенному флагу
(?x).
Функции
-
re.compile(pattern, flags=0) -
Компилирует шаблон регулярного выражения в объект регулярного выражения, который можно использовать для сопоставления с помощью его методов объекта регулярного выражения,
match(),search()и других, описанных ниже.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Последовательность
prog = re.compile(pattern) result = prog.match(string)
эквивалентна
result = re.match(pattern, string)
но использование
re.compile()и сохранение полученного объекта регулярного выражения для повторного использования более эффективно, когда выражение будет использоваться несколько раз в одной программе.Примечание
Компилированные версии последних шаблонов, переданные в
re.compile()и функции сопоставления на уровне модуля, кешируются, поэтому программам, использующим всего несколько регулярных выражений за раз, не нужно беспокоиться о компиляции регулярных выражений.
-
re.search(pattern, string, flags=0) -
Ищет в строке первое вхождение, где регулярное выражение pattern даёт совпадение, и возвращает соответствующий объект
Match. ВозвращаетNoneесли в строке не найдено совпадение; обратите внимание, что это отличается от нахождения совпадения нулевой длины в какой-либо точке строки.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).
-
re.match(pattern, string, flags=0) -
Если нуль или более символов в начале строки соответствуют регулярному выражению pattern, возвращает соответствующий объект
Match. ВозвращаетNoneесли строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.Обратите внимание, что даже в режиме
MULTILINE,re.match()будет соответствовать только началу строки, а не началу каждой строки.Если нужно найти совпадение где-либо в строке, используйте
search()(см. также search() vs. match()).Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).
-
re.fullmatch(pattern, string, flags=0) -
Если вся строка соответствует регулярному выражению pattern, возвращает соответствующий объект
Match. ВозвращаетNoneесли строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Добавлен в версии 3.4.
-
re.split(pattern, string, maxsplit=0, flags=0) -
Разделяет строку по вхождениям pattern. Если в pattern используются группирующие скобки, то текст всех групп в шаблоне также возвращается в качестве части результирующего списка. Если maxsplit не равно нулю, выполняется не более maxsplit разделений, и остаток строки возвращается как последний элемент списка.
>>> re.split(r'\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split(r'\W+', 'Words, words, words.', maxsplit=1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9']Если в разделителе есть группирующие скобки и он соответствует началу строки, результат будет начинаться с пустой строки. То же самое относится к концу строки:
>>> re.split(r'(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']
Таким образом, компоненты разделителя всегда находятся на тех же относительных индексах в списке результатов.
Пустые совпадения для шаблона разделяют строку только тогда, когда они не примыкают к предыдущему пустому совпадению.
>>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] >>> re.split(r'\W*', '...words...') ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.7: Добавлена поддержка разделения по шаблону, который может соответствовать пустой строке.
Устарело начиная с версии 3.13: Передача maxsplit и flags в качестве позиционных аргументов устарела. В будущих версиях Python они будут ключевыми параметрами.
-
re.findall(pattern, string, flags=0) -
Возвращает все неперекрывающиеся совпадения pattern в строке в виде списка строк или кортежей. Строка сканируется слева направо, а совпадения возвращаются в порядке их нахождения. Пустые совпадения включаются в результат.
Результат зависит от количества захватывающих групп в шаблоне. Если групп нет, возвращается список строк, соответствующих всему шаблону. Если есть ровно одна группа, возвращается список строк, соответствующих этой группе. Если присутствует несколько групп, возвращается список кортежей строк, соответствующих группам. Незакреплённые группы не влияют на форму результата.
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10') [('width', '20'), ('height', '10')]Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.
-
re.finditer(pattern, string, flags=0) -
Возвращает итератор, возвращающий объекты
Matchдля всех неперекрывающихся совпадений RE pattern в строке. Строка сканируется слева направо, а совпадения возвращаются в порядке их нахождения. Пустые совпадения включаются в результат.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.
-
re.sub(pattern, repl, string, count=0, flags=0) -
Возвращает строку, полученную путем замены всех неперекрывающихся вхождений шаблона в строке заменой repl. Если шаблон не найден, возвращается строка без изменений. repl может быть строкой или функцией; если это строка, все обратные слэши в ней обрабатываются. То есть,
\nпреобразуется в один символ новой строки,\rпреобразуется в символ возврата каретки, и так далее. Неизвестные эскейпы символов ASCII зарезервированы для будущего использования и обрабатываются как ошибки. Другие неизвестные эскейпы, такие как\&оставляются без изменений. Обратные ссылки, такие как\6, заменяются подстрокой, соответствующей группе 6 в шаблоне. Например:>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', ... r'static PyObject*\npy_\1(void)\n{', ... 'def myfunc():') 'static PyObject*\npy_myfunc(void)\n{'Если repl — функция, она вызывается для каждого неперекрывающегося вхождения шаблона. Функция принимает один аргумент
Matchи возвращает строку замены. Например:>>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' ... else: return '-' ... >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) 'Baked Beans & Spam'Шаблон может быть строкой или
Pattern.Необязательный аргумент count — максимальное число вхождений шаблона, которые будут заменены; count должен быть неотрицательным целым числом. Если он опущен или равен нулю, будут заменены все вхождения. Пустые совпадения шаблона заменяются только тогда, когда они не примыкают к предыдущему пустому совпадению, поэтому
sub('x*', '-', 'abxd')возвращает'-a-b--d-'.В строковых аргументах repl, помимо символьных эскейпов и обратных ссылок, описанных выше,
\g<name>будет использовать подстроку, соответствующую группе с именемname, как определено синтаксисом(?P<name>...).\g<number>использует соответствующий номер группы;\g<2>поэтому эквивалентен\2, но не является неоднозначным в замене, такой как\g<2>0.\20будет интерпретироваться как ссылка на группу 20, а не на группу 2, за которой следует буква'0'. Обратная ссылка\g<0>заменяет всю подстроку, соответствующую регулярному выражению.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.5: Несовпадающие группы заменяются пустой строкой.
Изменено в версии 3.6: Неизвестные эскейпы в шаблоне, состоящие из
'\'и буквы ASCII, теперь являются ошибками.Изменено в версии 3.7: Неизвестные эскейпы в repl, состоящие из
'\'и буквы ASCII, теперь являются ошибками. Пустые совпадения шаблона заменяются, если примыкают к предыдущему непустому совпадению.Изменено в версии 3.12: Идентификатор группы id может содержать только цифры ASCII. В строках замены
bytesимя группы name может содержать только байты в диапазоне ASCII (b'\x00'-b'\x7f').Устарело начиная с версии 3.13: Передача count и flags в качестве позиционных аргументов устарела. В будущих версиях Python они будут ключевыми параметрами.
-
re.subn(pattern, repl, string, count=0, flags=0) -
Выполняет ту же операцию, что и
sub(), но возвращает кортеж(new_string, number_of_subs_made).Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).
-
re.escape(pattern) -
Эскейпит специальные символы в шаблоне. Это полезно, если вы хотите сопоставить произвольную строку, которая может содержать метасимволы регулярных выражений. Например:
>>> print(re.escape('https://www.python.org')) https://www\.python\.org >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:" >>> print('[%s]+' % re.escape(legal_chars)) [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+ >>> operators = ['+', '-', '*', '/', '**'] >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*Эта функция не должна использоваться для строки замены в
sub()иsubn(), должны экранироваться только обратные слэши. Например:>>> digits_re = r'\d+' >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings' >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample)) /usr/sbin/sendmail - \d+ errors, \d+ warningsИзменено в версии 3.3: Символ
'_'больше не экранируется.Изменено в версии 3.7: Экранируются только символы, которые могут иметь специальное значение в регулярном выражении. В результате
'!','"','%',"'",',','/',':',';','<','=','>','@', и"`"больше не экранируются.
-
re.purge() -
Очистить кэш регулярных выражений.
Исключения
-
exception re.PatternError(msg, pattern=None, pos=None) -
Исключение, которое генерируется, когда строка, переданная одной из функций здесь, не является корректным регулярным выражением (например, может содержать несовпадающие скобки) или когда возникает какая-либо другая ошибка во время компиляции или сопоставления. Ошибка никогда не возникает, если строка не содержит совпадений с шаблоном. В экземпляре
PatternErrorесть следующие дополнительные атрибуты:-
msg -
Неформатированное сообщение об ошибке.
-
pattern -
Шаблон регулярного выражения.
-
pos -
Индекс в шаблоне, где произошла ошибка компиляции (может быть
None).
-
lineno -
Строка, соответствующая pos (может быть
None).
-
colno -
Столбец, соответствующий pos (может быть
None).
Изменено в версии 3.5: Добавлены дополнительные атрибуты.
Изменено в версии 3.13:
PatternErrorизначально называлсяerror; последний сохраняется как псевдоним для обратной совместимости. -
Объекты регулярных выражений
-
class re.Pattern -
Объект скомпилированного регулярного выражения, возвращаемый методом
re.compile().Изменено в версии 3.9:
re.Patternподдерживает[]для указания шаблона Unicode (str) или байтов. См. Тип обобщённого псевдонима.
-
Pattern.search(string[, pos[, endpos]]) -
Ищет в строке string первое вхождение шаблона регулярного выражения и возвращает соответствующий объект
Match. ВозвращаетNone, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от нахождения совпадения нулевой длины в какой-то точке строки.Необязательный второй параметр pos задаёт индекс в строке, с которого должно начинаться поиск; по умолчанию он равен
0. Это не полностью эквивалентно срезу строки; символ шаблона'^'соответствует началу строки и позициям сразу после символа новой строки, но не обязательно позиции, с которой начинается поиск.Необязательный параметр endpos ограничивает область поиска; как будто строка имеет длину endpos символов, так что будут проверятся только символы от pos до
endpos - 1. Если endpos меньше pos, совпадение не будет найдено. В противном случае, если rx — это объект скомпилированного регулярного выражения,rx.search(string, 0, 50)эквивалентноrx.search(string[:50], 0).>>> pattern = re.compile("d") >>> pattern.search("dog") # Match at index 0 <re.Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # No match; search doesn't include the "d"
-
Pattern.match(string[, pos[, endpos]]) -
Если нуль или более символов в начале строки string соответствуют этому регулярному выражению, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.Необязательные параметры pos и endpos имеют то же значение, что и для метода
search().>>> pattern = re.compile("o") >>> pattern.match("dog") # No match as "o" is not at the start of "dog". >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". <re.Match object; span=(1, 2), match='o'>Если требуется найти соответствие где-либо в string, используйте
search()(см. также search() против match()).
-
Pattern.fullmatch(string[, pos[, endpos]]) -
Если вся строка string соответствует этому регулярному выражению, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.Необязательные параметры pos и endpos имеют то же значение, что и для метода
search().>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. <re.Match object; span=(1, 3), match='og'>Добавлена в версии 3.4.
-
Pattern.split(string, maxsplit=0) -
Идентично функции
split(), использующей скомпилированный шаблон.
-
Pattern.findall(string[, pos[, endpos]]) -
Аналогично функции
findall(), использующей скомпилированный шаблон, но также принимает необязательные параметры pos и endpos, которые ограничивают область поиска, как дляsearch().
-
Pattern.finditer(string[, pos[, endpos]]) -
Аналогично функции
finditer(), использующей скомпилированный шаблон, но также принимает необязательные параметры pos и endpos, которые ограничивают область поиска, как дляsearch().
-
Pattern.sub(repl, string, count=0) -
Идентично функции
sub(), использующей скомпилированный шаблон.
-
Pattern.subn(repl, string, count=0) -
Идентично функции
subn(), использующей скомпилированный шаблон.
-
Pattern.flags -
Флаги соответствия регулярного выражения. Это комбинация флагов, заданных
compile(), любых флагов в шаблоне, и неявных флагов, таких какUNICODE, если шаблон — строка Unicode.
-
Pattern.groups -
Количество захватывающих групп в шаблоне.
-
Pattern.groupindex -
Словарь, сопоставляющий любые символические имена групп, определённые
(?P<id>), с номерами групп. Словарь пуст, если в шаблоне не было символических групп.
-
Pattern.pattern -
Строка шаблона, из которой был скомпилирован объект шаблона.
Изменено в версии 3.7: Добавлена поддержка copy.copy() и copy.deepcopy(). Объекты скомпилированных регулярных выражений считаются атомарными.
Объекты совпадений
Объекты совпадений всегда имеют булевое значение True. Поскольку match() и search() возвращают None при отсутствии совпадения, вы можете проверить, было ли совпадение, с помощью простого оператора if:
match = re.search(pattern, string)
if match:
process(match)
-
class re.Match -
Объект совпадения, возвращаемый успешными
matchиsearch.Изменено в версии 3.9:
re.Matchподдерживает[]для указания совпадения с Unicode (str) или байтами. См. Тип обобщённого псевдонима.
-
Match.expand(template) -
Возвращает строку, полученную путём подстановки обратных слэшей в шаблонную строку template, как это делает метод
sub(). Экранированные последовательности, такие как\nпреобразуются в соответствующие символы, а числовые обратные ссылки (\1,\2) и именованные обратные ссылки (\g<1>,\g<name>) заменяются содержимым соответствующей группы. Обратная ссылка\g<0>будет заменена на всё совпадение.Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.
-
Match.group([group1, ...]) -
Возвращает одну или несколько подгрупп совпадения. Если есть один аргумент, результат — одна строка; если есть несколько аргументов, результат — кортеж с одним элементом на каждый аргумент. Без аргументов group1 по умолчанию равен нулю (возвращается всё совпадение). Если аргумент groupN равен нулю, соответствующее возвращаемое значение — вся строка совпадения; если он находится в диапазоне [1..99], это строка, соответствующая соответствующей скобочной группе. Если номер группы отрицательный или больше, чем количество групп, определённых в шаблоне, генерируется исключение
IndexError. Если группа содержится в части шаблона, которая не сошлась, соответствующее значение —None. Если группа содержится в части шаблона, которая совпала несколько раз, возвращается последнее совпадение.>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") >>> m.group(0) # The entire match 'Isaac Newton' >>> m.group(1) # The first parenthesized subgroup. 'Isaac' >>> m.group(2) # The second parenthesized subgroup. 'Newton' >>> m.group(1, 2) # Multiple arguments give us a tuple. ('Isaac', 'Newton')Если регулярное выражение использует синтаксис
(?P<name>...), аргументы groupN также могут быть строками, идентифицирующими группы по их имени. Если строковый аргумент не используется как имя группы в шаблоне, генерируется исключениеIndexError.Умеренно сложный пример:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.group('first_name') 'Malcolm' >>> m.group('last_name') 'Reynolds'Именованные группы также можно ссылаться по их индексу:
>>> m.group(1) 'Malcolm' >>> m.group(2) 'Reynolds'
Если группа совпадает несколько раз, доступна только последняя:
>>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times. >>> m.group(1) # Returns only the last match. 'c3'
-
Match.__getitem__(g) -
Это идентично
m.group(g). Это позволяет проще получить доступ к отдельной группе из совпадения:>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") >>> m[0] # The entire match 'Isaac Newton' >>> m[1] # The first parenthesized subgroup. 'Isaac' >>> m[2] # The second parenthesized subgroup. 'Newton'
Поддерживаются также именованные группы:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton") >>> m['first_name'] 'Isaac' >>> m['last_name'] 'Newton'
Добавлен в версии 3.6.
-
Match.groups(default=None) -
Возвращает кортеж, содержащий все подгруппы совпадения, начиная с 1 до числа групп в шаблоне. Аргумент default используется для групп, не участвовавших в совпадении; по умолчанию он равен
None.Например:
>>> m = re.match(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632')Если мы сделаем десятичную точку и всё после неё необязательным, не все группы могут участвовать в совпадении. Эти группы будут по умолчанию
None, если аргумент default не задан:>>> m = re.match(r"(\d+)\.?(\d+)?", "24") >>> m.groups() # Second group defaults to None. ('24', None) >>> m.groups('0') # Now, the second group defaults to '0'. ('24', '0')
-
Match.groupdict(default=None) -
Возвращает словарь, содержащий все именованные подгруппы совпадения, с ключами, являющимися именами подгрупп. Аргумент default используется для групп, не участвовавших в совпадении; по умолчанию он равен
None. Например:>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.groupdict() {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
-
Match.start([group]) -
Match.end([group]) -
Возвращает индексы начала и конца подстроки, соответствующей group; group по умолчанию равен нулю (т.е. вся сопоставленная подстрока). Возвращает
-1если group существует, но не повлияла на совпадение. Для объекта совпадения m и группы g, которая повлияла на совпадение, подстрока, сопоставленная с группой g (эквивалентнаm.group(g)) равнаm.string[m.start(g):m.end(g)]
Обратите внимание, что
m.start(group)будет равноm.end(group)если group сопоставилась с пустой строкой. Например, послеm = re.search('b(c?)', 'cba'),m.start(0)равно 1,m.end(0)равно 2,m.start(1)иm.end(1)оба равны 2, аm.start(2)вызывает исключениеIndexError.Пример удаления remove_this из адресов электронной почты:
>>> email = "tony@tiremove_thisger.net" >>> m = re.search("remove_this", email) >>> email[:m.start()] + email[m.end():] 'tony@tiger.net'
-
Match.span([group]) -
Для совпадения m возвращает 2-кортеж
(m.start(group), m.end(group)). Обратите внимание, что если group не повлияла на совпадение, это(-1, -1). group по умолчанию равен нулю, всё совпадение.
-
Match.pos -
Значение pos, переданное методам
search()илиmatch()объекта объекта регулярного выражения. Это индекс в строке, с которого движок RE начал поиск совпадения.
-
Match.endpos -
Значение endpos, переданное методам
search()илиmatch()объекта объекта регулярного выражения. Это индекс в строке, за которым движок RE не пойдёт.
-
Match.lastindex -
Целочисленный индекс последней сопоставленной захватывающей группы или
Noneесли ни одна группа не сопоставлена. Например, выражения(a)b,((a)(b)), и((ab))будут иметьlastindex == 1при применении к строке'ab', тогда как выражение(a)(b)будет иметьlastindex == 2, если применён к той же строке.
-
Match.lastgroup -
Имя последней сопоставленной захватывающей группы или
Noneесли у группы нет имени или если ни одна группа не сопоставлена.
-
Match.re -
Объект регулярного выражения, метод
match()илиsearch()которого произвёл этот экземпляр совпадения.
Изменено в версии 3.7: Добавлена поддержка copy.copy() и copy.deepcopy(). Объекты совпадений считаются атомарными.
Примеры регулярных выражений
Проверка на пару
В этом примере мы воспользуемся следующей вспомогательной функцией для более удобного отображения объектов совпадения:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
Предположим, вы пишете программу для игры в покер, где рука игрока представлена строкой из 5 символов, каждый из которых представляет карту: «a» для туза, «k» для короля, «q» для дамы, «j» для валета, «t» для десятки, а «2» до «9» представляют карту с соответствующим значением.
Чтобы определить, является ли данная строка действительной рукой, можно сделать следующее:
>>> valid = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid.match("akt5q")) # Valid.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid.match("akt5e")) # Invalid.
>>> displaymatch(valid.match("akt")) # Invalid.
>>> displaymatch(valid.match("727ak")) # Valid.
"<Match: '727ak', groups=()>"
Последняя рука, "727ak", содержала пару, или две карты с одинаковым значением. Для сопоставления с этим регулярным выражением можно использовать обратные ссылки следующим образом:
>>> pair = re.compile(r".*(.).*\1")
>>> displaymatch(pair.match("717ak")) # Pair of 7s.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair.match("718ak")) # No pairs.
>>> displaymatch(pair.match("354aa")) # Pair of aces.
"<Match: '354aa', groups=('a',)>"
Чтобы узнать, какая карта составляет пару, можно использовать метод group() объекта совпадения следующим образом:
>>> pair = re.compile(r".*(.).*\1")
>>> pair.match("717ak").group(1)
'7'
# Error because re.match() returns None, which doesn't have a group() method:
>>> pair.match("718ak").group(1)
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
re.match(r".*(.).*\1", "718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'
>>> pair.match("354aa").group(1)
'a'
Моделирование scanf()
В Python в настоящее время нет эквивалента scanf(). Регулярные выражения, как правило, более мощные, хотя и более громоздкие, чем scanf() форматы строк. Таблица ниже предлагает более-менее эквивалентные соответствия между scanf() форматами и регулярными выражениями.
| Регулярное выражение |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Чтобы извлечь имя файла и числа из строки типа
/usr/sbin/sendmail - 0 errors, 4 warnings
вы бы использовали scanf() формат типа
%s - %d errors, %d warnings
Эквивалентным регулярным выражением было бы
(\S+) - (\d+) errors, (\d+) warnings
search() против match()
Python предлагает разные базовые операции, основанные на регулярных выражениях:
-
re.match()проверяет соответствие только в начале строки -
re.search()проверяет соответствие в любой части строки (это то, что Perl делает по умолчанию) -
re.fullmatch()проверяет, является ли вся строка соответствием
Например:
>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # Match
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # No match
Регулярные выражения, начинающиеся с '^', могут использоваться с search() для ограничения соответствия началом строки:
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<re.Match object; span=(0, 1), match='a'>
Однако обратите внимание, что в режиме MULTILINE match() соответствует только началу строки, тогда как использование search() с регулярным выражением, начинающимся с '^', будет соответствовать началу каждой строки.
>>> re.match("X", "A\nB\nX", re.MULTILINE) # No match
>>> re.search("^X", "A\nB\nX", re.MULTILINE) # Match
<re.Match object; span=(4, 5), match='X'>
Создание телефонной книги
split() разделяет строку на список, ограниченный переданным шаблоном. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые легко читать и изменять в Python, как показано в следующем примере, который создает телефонную книгу.
Сначала вот входные данные. Обычно они поступают из файла, здесь мы используем синтаксис строк с тройными кавычками
>>> text = """Ross McFluff: 834.345.1254 155 Elm Street ... ... Ronald Heathmore: 892.345.3428 436 Finley Avenue ... Frank Burger: 925.541.7625 662 South Dogwood Way ... ... ... Heather Albrecht: 548.326.4584 919 Park Place"""
Записи разделены одной или несколькими строками. Теперь мы преобразуем строку в список, где каждая непустая строка имеет свою запись:
>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']
Наконец, разделите каждую запись на список с именем, фамилией, номером телефона и адресом. Мы используем параметр maxsplit метода split(), потому что в адресе есть пробелы, наш разделитель.
>>> [re.split(":? ", entry, maxsplit=3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]
Шаблон :? соответствует двоеточию после фамилии, чтобы он не появлялся в результирующем списке. С maxsplit равным 4, мы могли бы разделить номер дома от названия улицы:
>>> [re.split(":? ", entry, maxsplit=4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
Обработка текста
sub() заменяет каждое вхождение шаблона строкой или результатом функции. Этот пример демонстрирует использование sub() с функцией для «обработки» текста или случайного изменения порядка всех символов в каждом слове предложения, кроме первых и последних символов:
>>> def repl(m): ... inner_word = list(m.group(2)) ... random.shuffle(inner_word) ... return m.group(1) + "".join(inner_word) + m.group(3) ... >>> text = "Professor Abdolmalek, please report your absences promptly." >>> re.sub(r"(\w)(\w+)(\w)", repl, text) 'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.' >>> re.sub(r"(\w)(\w+)(\w)", repl, text) 'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
Поиск всех наречий
findall() находит все вхождения шаблона, а не только первое, как search(). Например, если автор хотел найти все наречия в каком-то тексте, он мог бы использовать findall() следующим образом:
>>> text = "He was carefully disguised but captured quickly by police." >>> re.findall(r"\w+ly\b", text) ['carefully', 'quickly']
Поиск всех наречий и их позиций
Если кто-то хочет получить больше информации о всех совпадениях шаблона, чем сопоставленный текст, finditer() полезна, так как она предоставляет объекты Match, а не строки. Продолжая предыдущий пример, если автор хотел найти все наречия и их позиции в каком-то тексте, он бы использовал finditer() следующим образом:
>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
Нотация строк-сырья
Нотация строк-сырья (r"text") поддерживает регулярные выражения в корректном виде. Без нее каждый обратный слэш ('\') в регулярном выражении нужно было бы предварять еще одним, чтобы избежать его.
Например, две следующие строки кода функционально идентичны:
>>> re.match(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
Когда нужно сопоставить символ обратного слэша буквально, его нужно экранировать в регулярном выражении. С нотацией строк-сырья это означает r"\\". Без нотации строк-сырья нужно использовать "\\\\", что делает следующие строки кода функционально идентичными:
>>> re.match(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
Создание токенизатора
Токенизатор или сканер анализирует строку, чтобы классифицировать группы символов. Это полезный первый шаг при написании компилятора или интерпретатора.
Категории текста задаются с помощью регулярных выражений. Подход заключается в объединении их в одно общее регулярное выражение и переборе последовательных совпадений:
from typing import NamedTuple
import re
class Token(NamedTuple):
type: str
value: str
line: int
column: int
def tokenize(code):
keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
token_specification = [
('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
('ASSIGN', r':='), # Assignment operator
('END', r';'), # Statement terminator
('ID', r'[A-Za-z]+'), # Identifiers
('OP', r'[+\-*/]'), # Arithmetic operators
('NEWLINE', r'\n'), # Line endings
('SKIP', r'[ \t]+'), # Skip over spaces and tabs
('MISMATCH', r'.'), # Any other character
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group()
column = mo.start() - line_start
if kind == 'NUMBER':
value = float(value) if '.' in value else int(value)
elif kind == 'ID' and value in keywords:
kind = value
elif kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
continue
elif kind == 'SKIP':
continue
elif kind == 'MISMATCH':
raise RuntimeError(f'{value!r} unexpected on line {line_num}')
yield Token(kind, value, line_num, column)
statements = '''
IF quantity THEN
total := total + price * quantity;
tax := price * 0.05;
ENDIF;
'''
for token in tokenize(statements):
print(token)
Токенизатор производит следующий вывод:
Token(type='IF', value='IF', line=2, column=4) Token(type='ID', value='quantity', line=2, column=7) Token(type='THEN', value='THEN', line=2, column=16) Token(type='ID', value='total', line=3, column=8) Token(type='ASSIGN', value=':=', line=3, column=14) Token(type='ID', value='total', line=3, column=17) Token(type='OP', value='+', line=3, column=23) Token(type='ID', value='price', line=3, column=25) Token(type='OP', value='*', line=3, column=31) Token(type='ID', value='quantity', line=3, column=33) Token(type='END', value=';', line=3, column=41) Token(type='ID', value='tax', line=4, column=8) Token(type='ASSIGN', value=':=', line=4, column=12) Token(type='ID', value='price', line=4, column=15) Token(type='OP', value='*', line=4, column=21) Token(type='NUMBER', value=0.05, line=4, column=23) Token(type='END', value=';', line=4, column=27) Token(type='ENDIF', value='ENDIF', line=5, column=4) Token(type='END', value=';', line=5, column=9)
Фридл, Джеффри. Овладение регулярными выражениями. 3-е изд., O’Reilly Media, 2009. Третье издание книги больше не охватывает Python вообще, но первое издание подробно рассматривало написание хороших шаблонов регулярных выражений.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/re.html