re — Операции с регулярными выражениями
Исходный код: Lib/re/
Этот модуль предоставляет операции сопоставления регулярных выражений, аналогичные тем, что есть в Perl.
И шаблоны, и строки, которые будут проверяться, могут быть строками Юникода (str), а также строками 8-битных символов (bytes). Однако строки Юникода и строки 8-битных символов не могут быть смешаны: то есть вы не можете сопоставлять строку Юникода с шаблоном байтов или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон, и строка поиска.
Регулярные выражения используют обратную косую черту ('\') для обозначения специальных форм или для использования специальных символов без вызова их специального значения. Это конфликтует с использованием Python того же символа для той же цели в строковых литералах; например, чтобы сопоставить с образцом литеру обратную косую черту, нужно написать '\\\\' в качестве строки шаблона, поскольку регулярное выражение должно быть \\, а каждая обратная косая черта должна быть выражена как \\ внутри обычной строки Python. Также обратите внимание, что все недопустимые escape-последовательности в использовании обратной косой черты в строковых литералах Python теперь генерируют DeprecationWarning, а в будущем это станет SyntaxError. Это поведение будет происходить даже если это допустимая escape-последовательность для регулярного выражения.
Решение заключается в использовании обозначения сырых строк Python для шаблонов регулярных выражений; обратные косые черты не обрабатываются особым образом в строковом литерале, префикс которого 'r'. Таким образом, r"\n" — это строка из двух символов, содержащая '\' и 'n', а "\n" — это строка из одного символа, содержащая перевод строки. Обычно шаблоны будут выражаться в коде Python с использованием этого обозначения сырых строк.
Важно отметить, что большинство операций с регулярными выражениями доступны как функции уровня модуля и методы объектов скомпилированных регулярных выражений. Функции являются сокращениями, которые не требуют предварительной компиляции объекта regex, но пропустят некоторые параметры тонкой настройки.
См. также
Модуль сторонних разработчиков regex, у которого есть API, совместимый с модулем стандартной библиотеки re модуля, но он предлагает дополнительные возможности и более полную поддержку Юникода.
Синтаксис регулярных выражений
Регулярное выражение (или 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, это соответствует любому символу, включая новую строку.
-
^ -
(Знак возведения в степень.) Соответствует началу строки, а в режиме
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’; оно не будет соответствовать только ‘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 указывает нижнюю границу нуля, а пропуск 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', будет нуждаться в большем количестве символов, чем доступно, и, следовательно, не совпадёт, в то время какa{3,5}aaбудет соответствоватьa{3,5}, захватив 5, затем 4'a'отменяя, а затем последние 2'a'соответствуют последнемуaaв шаблоне.x{m,n}+эквивалентно(?>x{m,n}).Добавлен в версии 3.11.
-
\ -
Либо экранирует специальные символы (разрешая сопоставление символов, таких как
'*','?', и так далее), либо сигнализирует о специальной последовательности; специальные последовательности обсуждаются ниже.Если вы не используете строку без начального символа для выражения шаблона, помните, что Python также использует обратную косую черту в качестве escape-последовательности в строковых литералах; если escape-последовательность не распознается парсером 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(определены ниже), также принимаются внутри набора, хотя символы, которым они соответствуют, зависят от того, включён ли режимASCIIилиLOCALE.
- Символам, которые не входят в диапазон, можно соответствовать путём дополнения набора. Если первым символом набора является
'^', все символы, не входящие в набор, будут сопоставлены. Например,[^5]будет соответствовать любому символу, кроме'5', а[^^]будет соответствовать любому символу, кроме'^'.^не имеет особого значения, если это не первый символ в наборе. - Чтобы сопоставить буквальный
']'внутри набора, поместите перед ним обратную косую черту или поместите его в начало набора. Например, оба[()[\]{}]и[]()[{}]будут соответствовать правой квадратной скобке, а также левой квадратной скобке, фигурным скобкам и круглым скобкам.
- Поддержка вложенных наборов и операций над наборами, как в Unicode Technical Standard #18, может быть добавлена в будущем. Это изменит синтаксис, поэтому для облегчения этого изменения в неоднозначных случаях будет подниматься
FutureWarning. Это включает наборы, начинающиеся с буквального'['или содержащие буквальные последовательности символов'--','&&','~~', и'||'. Чтобы избежать предупреждения, экранируйте их обратной косой чертой.
Изменено в версии 3.7:
FutureWarningподнимается, если набор символов содержит конструкции, которые будут иметь семантически измениться в будущем. - Символы могут быть перечислены индивидуально, например,
-
| -
A|B, где A и B могут быть произвольными выражениями регулярных выражений, создает регулярное выражение, которое будет соответствовать либо A, либо B. Произвольное количество выражений RE может быть разделено'|'таким образом. Это можно использовать и внутри групп (см. ниже). По мере сканирования целевой строки выражения RE, разделенные'|', проверяются слева направо. Когда один шаблон полностью соответствует, эта ветвь принимается. Это означает, что как только A соответствует, B не будет проверяться дальше, даже если бы это дало более длинное соответствие в целом. Другими словами, оператор'|'никогда не жадный. Чтобы сопоставить буквальный'|', используйте\|, или заключите его в набор символов, как в[|].
-
(...) -
Сопоставляет любое регулярное выражение внутри скобок и указывает начало и конец группы; содержимое группы может быть извлечено после выполнения сопоставления и может быть сопоставлено позже в строке с помощью специальной последовательности
\number, описанной ниже. Чтобы сопоставить буквальные'('или')', используйте\(или\), или заключите их в набор символов:[(],[)].
-
(?...) -
Это обозначение расширения (
'?'после'('не имеет смысла в ином случае). Первый символ после'?'определяет смысл и дальнейший синтаксис конструкции. Расширения обычно не создают новой группы;(?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, и каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является пронумерованной группой, как если бы группа не имела имени.
Именованные группы могут быть использованы в трех контекстах. Если шаблон представляет собой
(?P<quote>['"]).*?(?P=quote)(т.е. сопоставляет строку, заключённую в одинарные или двойные кавычки):Контекст ссылки на группу "quote"
Способы ссылки на неё
в самом шаблоне
-
(?P=quote)(как показано) \1
при обработке объекта совпадения m
m.group('quote')-
m.end('quote')(и т.д.)
в строке, переданной в аргумент repl функции
re.sub()\g<quote>\g<1>\1
Устарело начиная с версии 3.11: Группа name, содержащая символы за пределами ASCII-диапазона (
b'\x00'-b'\x7f') в шаблонахbytes. -
-
(?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.11: Группа id, содержащая что-либо кроме ASCII-цифр. Группа name, содержащая символы за пределами ASCII-диапазона (
b'\x00'-b'\x7f') в строках заменыbytes.
Специальные последовательности состоят из '\' и символа из нижеследующего списка. Если обычный символ не является ASCII-цифрой или ASCII-буквой, то результирующее регулярное выражение будет сопоставляться со вторым символом. Например, \$ соответствует символу '$'.
-
\number -
Сопоставляется с содержимым группы с таким же номером. Группы нумеруются, начиная с 1. Например,
(.+) \1соответствует'the the'или'55 55', но не'thethe'(обратите внимание на пробел после группы). Эта специальная последовательность может быть использована только для сопоставления одной из первых 99 групп. Если первая цифра number равна 0 или number имеет длину 3 восьмеричных цифры, она не будет интерпретироваться как соответствие группе, а как символ с восьмеричным значением number. Внутри'['и']'класса символов все числовые эскейпы обрабатываются как символы.
-
\A -
Сопоставляется только в начале строки.
-
\b -
Сопоставляется с пустой строкой, но только в начале или конце слова. Слово определяется как последовательность символов слова. Обратите внимание, что формально
\bопределяется как граница между\wи\Wсимволами (или наоборот), или между\wи началом/концом строки. Это означает, чтоr'\bfoo\b'соответствует'foo','foo.','(foo)','bar foo baz', но не'foobar'или'foo3'.По умолчанию в Unicode-паттернах используются Unicode-алфанумерические символы, но это можно изменить, используя флаг
ASCII. Границы слов определяются текущей локалью, если используется флагLOCALE. Внутри диапазона символов\bпредставляет собой символ удаления, для совместимости с литералами строк Python.
-
\B -
Сопоставляется с пустой строкой, но только когда она не находится в начале или конце слова. Это означает, что
r'py\B'соответствует'python','py3','py2', но не'py','py.', или'py!'.\Bявляется просто обратным\b, поэтому символы слов в Unicode-паттернах — это Unicode-алфанумерические символы или подчёркивание, хотя это можно изменить, используя флагASCII. Границы слов определяются текущей локалью, если используется флагLOCALE.
-
\d -
- Для Unicode (str) шаблонов:
-
Сопоставляет любую десятичную цифру Unicode (то есть любой символ в категории Unicode-символов [Nd]). Это включает
[0-9], а также многие другие символы цифр. Если используется флагASCII, то сопоставляется только[0-9]. - Для 8-битных (bytes) шаблонов:
-
Сопоставляет любую десятичную цифру; это эквивалентно
[0-9].
-
\D -
Сопоставляет любой символ, который не является десятичной цифрой. Это противоположно
\d. Если используется флагASCII, это становится эквивалентом[^0-9].
-
\s -
- Для Unicode (str) шаблонов:
-
Сопоставляет символы Unicode-пробелов (включая
[ \t\n\r\f\v], а также многие другие символы, например, неразрывные пробелы, предписанные правилами типографики во многих языках). Если используется флагASCII, то сопоставляется только[ \t\n\r\f\v]. - Для 8-битных (bytes) шаблонов:
-
Сопоставляет символы, считающиеся пробелами в ASCII-символьной таблице; это эквивалентно
[ \t\n\r\f\v].
-
\S -
Сопоставляет любой символ, который не является символом пробела. Это противоположно
\s. Если используется флагASCII, это становится эквивалентом[^ \t\n\r\f\v].
-
\w -
- Для Unicode (str) шаблонов:
-
Совпадает с символами Unicode-слов; это включает буквенно-цифровые символы (как определено в
str.isalnum()), а также символ подчёркивания (_). Если используется флагASCII, то совпадает только[a-zA-Z0-9_]. - Для 8-битных (bytes) шаблонов:
-
Совпадает с символами, которые считаются буквенно-цифровыми в наборе символов ASCII; это эквивалентно
[a-zA-Z0-9_]. Если используется флагLOCALE, совпадают символы, которые считаются буквенно-цифровыми в текущем языке и подчёркивание.
-
\W -
Совпадает с любым символом, который не является символом слова. Это противоположность
\w. Если используется флагASCII, это становится эквивалентным[^a-zA-Z0-9_]. Если используется флагLOCALE, совпадают символы, которые не являются буквенно-цифровыми в текущем языке и не являются подчёркиванием.
-
\Z -
Совпадает только в конце строки.
Большинство стандартных эскейпов, поддерживаемых литералами строк Python, также принимаются парсером регулярных выражений:
\a \b \f \n \N \r \t \u \U \v \x \\
(Обратите внимание, что \b используется для представления границ слов и означает «ввод», только внутри классов символов.)
'\u', '\U', и '\N' последовательности эскейпов распознаются только в Unicode-шаблонах. В шаблонах байтов они являются ошибками. Неизвестные эскейпы 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 -
Заставить
\w,\W,\b,\B,\d,\D,\sи\Sвыполнять соответствие только символам ASCII вместо полного соответствия Unicode. Это имеет смысл только для шаблонов Unicode и игнорируется для байтовых шаблонов. Соответствует встроенному флагу(?a).Обратите внимание, что для обратной совместимости флаг
re.Uвсе еще существует (а также его синонимre.UNICODEи его встроенный аналог(?u)), но они избыточны в Python 3, так как соответствие по умолчанию для строк — Unicode (и соответствие Unicode не допускается для байтов).
-
re.DEBUG -
Отображать отладочную информацию о скомпилированном выражении. Нет соответствующего встроенного флага.
-
re.I -
re.IGNORECASE -
Выполнять регистронезависимое соответствие; выражения, такие как
[A-Z], также будут соответствовать строчным буквам. Полное соответствие Unicode (например,Üсоответствуетü), также работает, если не используется флагre.ASCIIдля отключения соответствий не-ASCII. Текущий локали не влияет на действие этого флага, если не используется также флагre.LOCALE. Соответствует встроенному флагу(?i).Обратите внимание, что при использовании шаблонов Unicode
[a-z]или[A-Z]в сочетании с флагомIGNORECASE, они будут соответствовать 52 ASCII буквам и 4 дополнительным не-ASCII буквам: ‘İ’ (U+0130, латинская заглавная буква I с точкой сверху), ‘ı’ (U+0131, латинская строчная буква без точки i), ‘ſ’ (U+017F, латинская строчная буква длинное s) и ‘K’ (U+212A, знак Кельвина). Если используется флагASCII, будут соответствовать только буквы ‘a’ до ‘z’ и ‘A’ до ‘Z’.
-
re.L -
re.LOCALE -
Заставить
\w,\W,\b,\Bи регистронезависимое соответствие зависеть от текущей локали. Этот флаг можно использовать только с байтовыми шаблонами. Использование этого флага не рекомендуется, так как механизм локали очень ненадежен, он обрабатывает только одну «культуру» за раз, и он работает только с 8-битными локалями. Соответствие Unicode уже включено по умолчанию в Python 3 для шаблонов Unicode (str), и он может обрабатывать различные локали/языки. Соответствует встроенному флагу(?L).Изменено в версии 3.6:
re.LOCALEможет использоваться только с байтовыми шаблонами и несовместим сre.ASCII.Изменено в версии 3.7: Объекты скомпилированных регулярных выражений с флагом
re.LOCALEбольше не зависят от локали во время компиляции. Только локаль во время сопоставления влияет на результат сопоставления.
-
re.M -
re.MULTILINE -
При указании символ шаблона
'^'соответствует началу строки и началу каждой строки (непосредственно после каждого символа новой строки); и символ шаблона'$'соответствует концу строки и концу каждой строки (непосредственно перед каждым символом новой строки). По умолчанию'^'соответствует только началу строки, и'$'только концу строки и непосредственно перед символом новой строки (если есть) в конце строки.
-
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 2 этот флаг заставлял специальные последовательности включать символы Unicode в совпадения. С Python 3 символы Unicode соответствуют по умолчанию.
См.
Aдля ограничения соответствия на символы 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) -
Ищет в строке первое место, где регулярное выражение шаблон производит совпадение, и возвращает соответствующий объект
Match. ВозвращаетNoneесли ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в какой-либо точке строки.
-
re.match(pattern, string, flags=0) -
Если ноль или более символов в начале строки соответствуют регулярному выражению шаблон, возвращает соответствующий объект
Match. ВозвращаетNoneесли строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.Обратите внимание, что даже в режиме
MULTILINEre.match()будет соответствовать только началу строки, а не началу каждой строки.Если требуется найти совпадение в любой точке строки, используйте
search()вместо этого (см. также search() vs. match()).
-
re.fullmatch(pattern, string, flags=0) -
Если вся строка соответствует регулярному выражению шаблон, возвращает соответствующий объект
Match. ВозвращаетNoneесли строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.New in version 3.4.
-
re.split(pattern, string, maxsplit=0, flags=0) -
Разделяет строку по вхождениям шаблона. Если в шаблоне используются группы захвата, то текст всех групп в шаблоне также возвращается в качестве части результирующего списка. Если 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.', 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', '...', '', '', '']
Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.7: Добавлена поддержка разделения по шаблону, который может соответствовать пустой строке.
-
re.findall(pattern, string, flags=0) -
Возвращает все неперекрывающиеся совпадения шаблона в строке в виде списка строк или кортежей. Строка сканируется слева направо, и совпадения возвращаются в порядке их нахождения. Пустые совпадения включаются в результат.
Результат зависит от количества групп захвата в шаблоне. Если групп нет, возвращается список строк, соответствующих всему шаблону. Если есть ровно одна группа, возвращается список строк, соответствующих этой группе. Если присутствуют несколько групп, возвращается список кортежей строк, соответствующих группам. Незахватывающие группы не влияют на форму результата.
>>> 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')]Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.
-
re.finditer(pattern, string, flags=0) -
Возвращает итератор, возвращающий объекты
Matchдля всех неперекрывающихся совпадений RE шаблон в строке. Строка сканируется слева направо, и совпадения возвращаются в порядке их нахождения. Пустые совпадения включаются в результат.Изменено в версии 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>заменяет всю подстроку, соответствующую RE.Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.5: Несоответствующие группы заменяются пустой строкой.
Изменено в версии 3.6: Неизвестные эскейпы в pattern, состоящие из
'\'и ASCII буквы, теперь являются ошибками.Изменено в версии 3.7: Неизвестные эскейпы в repl, состоящие из
'\'и ASCII буквы, теперь являются ошибками.Изменено в версии 3.7: Пустые совпадения шаблона заменяются, когда они прилегают к предыдущему непустому совпадению.
Устарело начиная с версии 3.11: Группа id, содержащая что-либо кроме ASCII цифр. Группа name, содержащая символы за пределами ASCII диапазона (
b'\x00'-b'\x7f') в строках заменыbytes.
-
re.subn(pattern, repl, string, count=0, flags=0) -
Выполняет ту же операцию, что и
sub(), но возвращает кортеж(new_string, number_of_subs_made).Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.5: Несоответствующие группы заменяются пустой строкой.
-
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.error(msg, pattern=None, pos=None) -
Исключение, выбрасываемое, когда строка, переданная одной из функций, не является допустимым регулярным выражением (например, она может содержать несовпадающие скобки) или когда возникает какая-либо другая ошибка во время компиляции или сопоставления. Ошибка никогда не возникает, если строка не содержит совпадения с шаблоном. Объект ошибки имеет следующие дополнительные атрибуты:
-
msg -
Неформатированное сообщение об ошибке.
-
pattern -
Шаблон регулярного выражения.
-
pos -
Индекс в шаблоне, где произошла ошибка компиляции (может быть
None).
-
lineno -
Строка, соответствующая pos (может быть
None).
-
colno -
Столбец, соответствующий pos (может быть
None).
Изменено в версии 3.5: Добавлены дополнительные атрибуты.
-
Объекты регулярных выражений
-
class re.Pattern -
Объект скомпилированного регулярного выражения, возвращаемый функцией
re.compile().Изменено в версии 3.9:
re.Patternподдерживает[]для указания Unicode (str) или байтового шаблона. См. Тип обобщенного псевдонима.
-
Pattern.search(string[, pos[, endpos]]) -
Просматривает строку, ища первое местоположение, где это регулярное выражение даёт совпадение, и возвращает соответствующий
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]]) -
Если ноль или более символов в начале строки соответствуют этому регулярному выражению, возвращает соответствующий
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'>Если вы хотите найти совпадение где угодно в строке, используйте
search()(см. также search() против match()).
-
Pattern.fullmatch(string[, pos[, endpos]]) -
Если вся строка соответствует этому регулярному выражению, возвращает соответствующий
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, если шаблон является строкой Юникода.
-
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>) заменяются содержимым соответствующей группы.Изменено в версии 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 по умолчанию равен нулю (вся сопоставленная подстрока). Возвращает
-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, 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, 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)
-
Frie09 -
Фридл, Джеффри. Овладение регулярными выражениями. 3-е изд., O’Reilly Media, 2009. Третье издание книги больше не охватывает Python вообще, но первое издание подробно рассматривало создание хороших шаблонов регулярных выражений.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/re.html