re — Операции с регулярными выражениями
Исходный код: Lib/re/
Этот модуль предоставляет операции сопоставления с регулярными выражениями, аналогичные тем, которые есть в Perl.
И шаблоны, и строки, которые будут проверяться, могут быть строками Unicode (str), а также строками 8-битных символов (bytes). Однако строки Unicode и строки 8-битных символов не могут быть смешаны: то есть вы не можете сопоставить строку Unicode с шаблоном байтов или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон, и строка поиска.
Регулярные выражения используют обратную косую черту ('\') для обозначения специальных форм или для того, чтобы специальные символы использовались без вызова их специального значения. Это конфликтует с использованием Python того же символа для той же цели в строковых литералах; например, для сопоставления с литерой обратной косой черты необходимо написать '\\\\' в качестве строки шаблона, потому что регулярное выражение должно быть \\, а каждая обратная косая черта должна быть выражена как \\ внутри обычной строки Python. Кроме того, обратите внимание, что любые некорректные escape-последовательности в использовании Python обратной косой черты в строковых литералах сейчас генерируют SyntaxWarning, а в будущем это станет SyntaxError. Это поведение произойдёт даже если это допустимая escape-последовательность для регулярного выражения.
Решение заключается в использовании синтаксиса «сырых строк» 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’; оно не будет соответствовать только ‘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специальной последовательности, описанной ниже. Чтобы сопоставить буквальные'('или')', используйте\(или\), или заключите их в набор символов:[(],[)].
-
(?...) -
Это обозначение расширения (
'?'после'('в противном случае не имеет смысла). Первый символ после'?'определяет смысл и дальнейший синтаксис конструкции. Расширения обычно не создают новых групп;(?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 (строки) — это Unicode-буквенно-цифровые символы и символ подчёркивания, но это можно изменить, используя флаг
ASCII. Границы слов определяются текущей локалью, если используется флагLOCALE.Примечание
Внутри диапазона символов
\bпредставляет символ возврата в начало строки, для совместимости с строковыми литералами Python.
-
\B -
Соответствует пустой строке, но только когда она не находится в начале или конце слова. Это означает, что
r'at\B'соответствует'athens','atom','attorney', но не'at','at.', или'at!'.\Bявляется противоположностью\b, поэтому символы слов в шаблонах Unicode (строки) — это Unicode-буквенно-цифровые символы или символ подчёркивания, хотя это можно изменить, используя флагASCII. Границы слов определяются текущей локалью, если используется флагLOCALE.
-
\d -
- Для шаблонов Unicode (строки):
-
Соответствует любому десятичному знаку Unicode (т.е. любому символу в категории Unicode [Nd]). Это включает в себя
[0-9], а также многие другие цифровые символы.Соответствует
[0-9], если используется флагASCII. - Для шаблонов 8-битных (байты):
-
Соответствует любой десятичной цифре в наборе ASCII-символов; это эквивалентно
[0-9].
-
\D -
Соответствует любому символу, который не является десятичной цифрой. Это противоположность
\d.Соответствует
[^0-9], если используется флагASCII.
-
\s -
- Для шаблонов Unicode (строки):
-
Соответствует символам Unicode-пробелов (включая
[ \t\n\r\f\v], а также многие другие символы, например, неразрывные пробелы, предписанные правилами типографики во многих языках).Соответствует
[ \t\n\r\f\v], если используется флагASCII. - Для шаблонов 8-битных (байты):
-
Соответствует символам, которые считаются пробелами в наборе ASCII-символов; это эквивалентно
[ \t\n\r\f\v].
-
\S -
Соответствует любому символу, который не является символом пробела. Это противоположность
\s.Соответствует
[^ \t\n\r\f\v], если используется флагASCII.
-
\w -
- Для шаблонов Юникода (str):
-
Соответствует символам Юникода, включая все символы Юникода-алфавитно-цифрового набора (как определено в
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' последовательности экранирования распознаются только в шаблонах Юникода (str). В шаблонах bytes они являются ошибками. Неизвестные ASCII-экранированные символы зарезервированы для будущего использования и обрабатываются как ошибки.
Восьмеричные escapes включены в ограниченной форме. Если первая цифра — 0, или если есть три восьмеричных цифры, она считается восьмеричным escape. В противном случае это ссылка на группу. Как и в строковых литералах, восьмеричные escapes всегда имеют длину не более трёх цифр.
Изменено в версии 3.3: Были добавлены последовательности экранирования '\u' и '\U'.
Изменено в версии 3.6: Неизвестные escapes, состоящие из '\' и буквы ASCII, теперь являются ошибками.
Изменено в версии 3.8: Была добавлена последовательность экранирования '\N{name}'. Как и в строковых литералах, она расшифровывается до указанного символа Юникода (например, '\N{EM DASH}').
Содержание модуля
Модуль определяет несколько функций, констант и исключение. Некоторые функции являются упрощенными версиями полных методов для скомпилированных регулярных выражений. Большинство нетривиальных приложений всегда используют скомпилированную форму.
Флаги
Изменено в версии 3.6: Константы флагов теперь являются экземплярами RegexFlag, который является подклассом enum.IntFlag.
-
class re.RegexFlag -
Класс
enum.IntFlag, содержащий опции регулярных выражений, перечисленные ниже.Добавлен в версии 3.11: - добавлен в
__all__
-
re.A -
re.ASCII -
Выполнить сопоставление только с ASCII-символами вместо полного Unicode-сопоставления для
\w,\W,\b,\B,\d,\D,\sи\S. Это имеет смысл только для Unicode (str) шаблонов и игнорируется для шаблонов типа bytes.Соответствует встроенному флагу
(?a).
-
re.DEBUG -
Отображение отладочной информации о скомпилированном выражении.
Нет соответствующего встроенного флага.
-
re.I -
re.IGNORECASE -
Выполнение сопоставления без учета регистра; выражения, подобные
[A-Z], также будут соответствовать строчным буквам. Полное Unicode-сопоставление (например,Üсоответствуетü) также работает, если не используется флагASCIIдля отключения сопоставлений, не являющихся ASCII. Текущий локали не влияет на действие этого флага, если не используется также флаг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и сопоставление без учета регистра, зависящим от текущей локали. Этот флаг может быть использован только с шаблонами типа bytes.Соответствует встроенному флагу
(?L).Предупреждение
Использование этого флага не рекомендуется; рассмотрите Unicode-сопоставления вместо него. Механизм локали очень ненадежен, так как он обрабатывает только одну «культуру» за раз и работает только с 8-битными локалями. Unicode-сопоставление включено по умолчанию для Unicode (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 Unicode-символы соответствуют по умолчанию для шаблонов
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) -
Просматривает строку, ища первое местоположение, где регулярное выражение шаблон создаёт соответствие, и возвращает соответствующий объект
Match. ВозвращаетNone, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска соответствия нулевой длины в какой-либо точке строки.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).
-
re.match(pattern, string, flags=0) -
Если ноль или более символов в начале строки соответствуют регулярному выражению шаблон, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это отличается от соответствия нулевой длины.Обратите внимание, что даже в режиме
MULTILINE,re.match()будет соответствовать только в начале строки, а не в начале каждой строки.Если требуется найти соответствие где-либо в строке, используйте
search()(см. также search() против match()).Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).
-
re.fullmatch(pattern, string, flags=0) -
Если вся строка соответствует регулярному выражению шаблон, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это отличается от соответствия нулевой длины.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Добавлен в версии 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', '...', '', '', '']
Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 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')]Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 3.7: Теперь непустые соответствия могут начинаться сразу после предыдущего пустого соответствия.
-
re.finditer(pattern, string, flags=0) -
Возвращает итератор, генерирующий объекты
Matchпо всем неперекрывающимся соответствиям RE шаблон в строке. Строка сканируется слева направо, а совпадения возвращаются в порядке их обнаружения. Пустые соответствия включаются в результат.Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).Изменено в версии 3.7: Теперь непустые соответствия могут начинаться сразу после предыдущего пустого соответствия.
-
re.sub(pattern, repl, string, count=0, flags=0) -
Возвращает строку, полученную путём замены всех неперекрывающихся вхождения шаблона pattern в строке string заменой repl. Если шаблон не найден, возвращается исходная строка string без изменений. 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 является функцией, она вызывается для каждого неперекрывающегося вхождения pattern. Функция принимает один аргумент
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: Неизвестные эскейпы в pattern, состоящие из
'\'и буквы ASCII, теперь являются ошибками.Изменено в версии 3.7: Неизвестные эскейпы в repl, состоящие из
'\'и буквы ASCII, теперь являются ошибками.Изменено в версии 3.7: Пустые совпадения шаблона заменяются прилеганием к предыдущему непустому совпадению.
Изменено в версии 3.12: Идентификатор группы id может содержать только цифры ASCII. В строках замены
bytes, имя группы name может содержать только байты в диапазоне ASCII (b'\x00'-b'\x7f').
-
re.subn(pattern, repl, string, count=0, flags=0) -
Выполняет ту же операцию, что и
sub(), но возвращает кортеж(new_string, number_of_subs_made).Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.5: Несовпадающие группы заменяются пустой строкой.
Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из переменных флагов, объединённых с помощью побитового ИЛИ (оператора
|).
-
re.escape(pattern) -
Экранирует специальные символы в 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 -
Индекс в pattern, где произошла ошибка компиляции (может быть
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]]) -
Ищет в строке 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()объекта объекта regex. Это индекс в строке, с которого движок RE начал поиск совпадения.
-
Match.endpos -
Значение endpos, которое было передано методу
search()илиmatch()объекта объекта regex. Это индекс в строке, дальше которого движок 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» для 10, а «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)
Фридл, Джеффри. Искусство регулярных выражений. 3-е изд., O’Reilly Media, 2009. Третье издание книги больше не охватывает Python вообще, но первое издание подробно описывало составление хороших шаблонов регулярных выражений.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/re.html