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, API которого совместим со стандартным библиотечным модулем re, но который предоставляет дополнительные возможности и более полную поддержку Unicode.
Синтаксис регулярных выражений
Регулярное выражение (или RE) задаёт множество строк, которым оно соответствует; функции этого модуля позволяют проверить, соответствует ли определённая строка заданному регулярному выражению (или соответствует ли заданное регулярное выражение определённой строке — по сути, это одно и то же).
Регулярные выражения можно конкатенировать, чтобы образовывать новые регулярные выражения; если A и B — регулярные выражения, то AB также является регулярным выражением. В общем случае, если строка p соответствует A, а другая строка q соответствует B, то строка pq будет соответствовать AB. Это верно, если только A или B не содержат операций с низким приоритетом; граничных условий между A и B; или ссылок на нумерованные группы. Таким образом, сложные выражения можно легко составлять из более простых элементарных выражений, описанных здесь. За сведениями о теории и реализации регулярных выражений обратитесь к книге Фридла [Frie09] или почти к любому учебнику по построению компиляторов.
Ниже приводится краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более доступного изложения обратитесь к руководству по регулярным выражениям.
Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, например 'A', 'a' или '0', — это простейшие регулярные выражения; они просто соответствуют самим себе. Обычные символы можно объединять в последовательности, поэтому last соответствует строке 'last'. (Далее в этом разделе регулярные выражения будут записываться в 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’, но в режимеMULTILINE— ‘foo1’; поиск одного$в'foo\n'найдёт два (пустых) совпадения: одно непосредственно перед символом новой строки, а другое — в конце строки.
-
* -
Заставляет полученное регулярное выражение соответствовать нулю или большему числу повторений предшествующего регулярного выражения, максимально возможному.
ab*соответствует ‘a’, ‘ab’ или ‘a’, за которым следует любое количество символов ‘b’.
-
+ -
Заставляет полученное регулярное выражение соответствовать одному или большему числу повторений предшествующего регулярного выражения.
ab+соответствует ‘a’, за которым следует ненулевое количество символов ‘b’; просто ‘a’ ему не соответствует.
-
? -
Заставляет полученное регулярное выражение соответствовать нулю или одному повторению предшествующего регулярного выражения.
ab?соответствует либо ‘a’, либо ‘ab’.
-
*?, +?, ?? -
Квантификаторы
'*','+'и'?'являются жадными: они сопоставляют максимально возможное количество текста. Иногда такое поведение нежелательно; если применить регулярное выражение<.*>к'<a> b <c>', оно будет соответствовать всей строке, а не только'<a>'. Если добавить?после квантификатора, сопоставление будет нежадным, или минимальным: будет сопоставлено как можно меньше символов. Регулярное выражение<.*?>будет соответствовать только'<a>'.
-
*+, ++, ?+ -
Как и квантификаторы
'*','+'и'?', квантификаторы с добавленным'+'также сопоставляют максимально возможное количество повторений. Однако, в отличие от обычных жадных квантификаторов, они не допускают возврата при неудачном сопоставлении следующего выражения. Такие квантификаторы называются обладающими жадностью без возврата (possessive). Например,a*aсоответствует'aaaa', посколькуa*сопоставит все 4 символа'a', но при встрече последнего'a'выражение вернётся назад, и в итогеa*сопоставит всего 3 символа'a', а четвёртый'a'будет сопоставлен последним'a'. Однако при использованииa*+aдля сопоставления с'aaaa'выражениеa*+сопоставит все 4 символа'a', но когда последний'a'не найдёт больше символов для сопоставления, выражение не сможет вернуться назад, и сопоставление завершится неудачей.x*+,x++иx?+эквивалентны соответственно(?>x*),(?>x+)и(?>x?).Добавлено в версии 3.11.
-
{m} -
Указывает, что должно быть сопоставлено ровно m копий предыдущего регулярного выражения; если совпадений окажется меньше, всё регулярное выражение не будет соответствовать строке. Например,
a{6}соответствует ровно шести символам'a', но не пяти. -
{m,n} -
Заставляет полученное регулярное выражение соответствовать от m до n повторений предшествующего регулярного выражения, пытаясь сопоставить максимально возможное количество повторений. Например,
a{3,5}соответствует от 3 до 5 символам'a'. Если опустить m, нижняя граница будет равна нулю; если опустить n, верхняя граница будет бесконечной. Например,a{4,}bсоответствует'aaaab'или тысяче символов'a', за которыми следует'b', но не'aaab'. Запятую опускать нельзя, иначе этот модификатор будет спутан с описанной выше формой. -
{m,n}? -
Заставляет полученное регулярное выражение соответствовать от m до n повторений предшествующего регулярного выражения, пытаясь сопоставить как можно меньше повторений. Это нежадная версия предыдущего квантификатора. Например, для строки из 6 символов
'aaaaaa'выражениеa{3,5}сопоставит 5 символов'a', тогда какa{3,5}?сопоставит только 3 символа. -
{m,n}+ -
Заставляет полученное регулярное выражение соответствовать от m до n повторений предшествующего регулярного выражения, пытаясь сопоставить максимально возможное количество повторений, не устанавливая точек возврата. Это версия предыдущего квантификатора, обладающая жадностью без возврата. Например, для строки из 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 также использует обратную косую черту как символ экранирования в строковых литералах; если последовательность экранирования не распознаётся синтаксическим анализатором 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 № 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(подробный режим)
(Флаги описаны в разделе Содержимое модуля.) Это полезно, если вы хотите включить флаги в регулярное выражение, а не передавать аргумент flag функции
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}. Обратите внимание: шаблоны, начинающиеся с положительных утверждений просмотра назад, не будут соответствовать началу строки, в которой выполняется поиск; скорее всего, вместо функцииmatch()вам понадобится функцияsearch():>>> 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, полученное регулярное выражение будет соответствовать этому второму символу. Например, \$ соответствует символу '$'.
-
\number -
Соответствует содержимому группы с тем же номером. Нумерация групп начинается с 1. Например,
(.+) \1соответствует'the the'или'55 55', но не'thethe'(обратите внимание на пробел после группы). Эту специальную последовательность можно использовать только для сопоставления с одной из первых 99 групп. Если первая цифра number равна 0 или number состоит из 3 восьмеричных цифр, последовательность будет интерпретирована не как ссылка на группу, а как символ с восьмеричным значением number. Внутри'['и']'символьного класса все числовые escape-последовательности считаются символами.
-
\A -
Соответствует только в начале строки.
-
\b -
Соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность символов слова. Формально
\bопределяется как граница между символом\wи символом\W(или наоборот), а также между\wи началом или концом строки. Это означает, чтоr'\bat\b'соответствует'at','at.','(at)'и'as at ay', но не'attempt'или'atlas'.По умолчанию символами слова в шаблонах Unicode (str) являются буквенно-цифровые символы Unicode и знак подчёркивания, но это можно изменить с помощью флага
ASCII. Если используется флагLOCALE, границы слов определяются текущей локалью.Примечание
Внутри диапазона символов
\bобозначает символ возврата на одну позицию (backspace) для совместимости со строковыми литералами Python.
-
\B -
Соответствует пустой строке, но только если она не находится в начале или конце слова. Это означает, что
r'at\B'соответствует'athens','atom','attorney', но не'at','at.'или'at!'.\Bпротивоположно\b, поэтому символами слова в шаблонах Unicode (str) считаются буквенно-цифровые символы Unicode или знак подчёркивания, хотя это можно изменить с помощью флагаASCII. Если используется флагLOCALE, границы слов определяются текущей локалью.Примечание
Обратите внимание, что
\Bне соответствует пустой строке, в отличие от реализаций RE в других языках программирования, например Perl. Такое поведение сохранено для обеспечения совместимости.
-
\d -
- Для шаблонов Unicode (str):
-
Соответствует любой десятичной цифре Unicode (то есть любому символу категории символов Unicode [Nd]). Сюда входят
[0-9], а также многие другие цифровые символы.Соответствует
[0-9], если используется флагASCII. - Для 8-битных шаблонов (bytes):
-
Соответствует любой десятичной цифре из набора символов ASCII; это эквивалентно
[0-9].
-
\D -
Соответствует любому символу, который не является десятичной цифрой. Это противоположность
\d.Соответствует
[^0-9], если используется флагASCII.
-
\s -
- Для шаблонов Unicode (str):
-
Соответствует пробельным символам Unicode (как определено в
str.isspace()). Сюда входят[ \t\n\r\f\v], а также многие другие символы, например неразрывные пробелы, предписанные правилами типографики во многих языках.Соответствует
[ \t\n\r\f\v], если используется флагASCII. - Для 8-битных шаблонов (bytes):
-
Соответствует символам, которые считаются пробельными в наборе символов ASCII; это эквивалентно
[ \t\n\r\f\v].
-
\S -
Соответствует любому символу, который не является пробельным. Это противоположность
\s.Соответствует
[^ \t\n\r\f\v], если используется флагASCII.
-
\w -
- Для шаблонов Unicode (str):
-
Соответствует словесным символам Unicode; сюда входят все буквенно-цифровые символы Unicode (как определено в
str.isalnum()), а также символ подчёркивания (_).Соответствует
[a-zA-Z0-9_], если используется флагASCII. - Для 8-битных шаблонов (bytes):
-
Соответствует символам, которые считаются буквенно-цифровыми в наборе символов ASCII; это эквивалентно
[a-zA-Z0-9_]. Если используется флагLOCALE, соответствуют символы, считающиеся буквенно-цифровыми в текущей локали, а также символ подчёркивания.
-
\W -
Соответствует любому символу, который не является словесным символом. Это противоположность
\w. По умолчанию соответствуют символы, не являющиеся подчёркиванием (_), для которыхstr.isalnum()возвращаетFalse.Соответствует
[^a-zA-Z0-9_], если используется флагASCII.Если используется флаг
LOCALE, соответствуют символы, которые в текущей локали не являются ни буквенно-цифровыми, ни символом подчёркивания.
-
\Z -
Соответствует только в конце строки.
Большинство последовательностей экранирования, поддерживаемых строковыми литералами Python, также принимаются парсером регулярных выражений:
\a \b \f \n \N \r \t \u \U \v \x \\
(Обратите внимание, что \b используется для обозначения границ слов и означает «забой» только внутри классов символов.)
Последовательности экранирования '\u', '\U' и '\N' распознаются только в шаблонах Unicode (str). В шаблонах bytes они вызывают ошибки. Неизвестные escape-последовательности с буквами ASCII зарезервированы для будущего использования и считаются ошибками.
В ограниченной форме поддерживаются восьмеричные escape-последовательности. Если первая цифра — 0 или если указаны три восьмеричные цифры, последовательность считается восьмеричной escape-последовательностью. В противном случае это ссылка на группу. Как и в строковых литералах, длина восьмеричных escape-последовательностей не превышает трёх цифр.
Изменено в версии 3.3: Добавлены последовательности экранирования '\u' и '\U'.
Изменено в версии 3.6: Неизвестные escape-последовательности, состоящие из '\' и буквы 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 (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, строчная латинская буква без точки), ‘ſ’ (U+017F, строчная латинская буква s длинная) и ‘K’ (U+212A, знак кельвина). Если используется флагASCII, сопоставляются только буквы от ‘a’ до ‘z’ и от ‘A’ до ‘Z’.
-
re.L -
re.LOCALE -
Заставляет
\w,\W,\b,\Bи сопоставление без учёта регистра зависеть от текущей локали. Этот флаг можно использовать только с шаблонами bytes.Соответствует встроенному флагу
(?L).Предупреждение
Использование этого флага не рекомендуется; рассмотрите возможность сопоставления с Unicode. Механизм локалей крайне ненадёжен, поскольку одновременно обрабатывает только одну «культуру» и работает только с 8-битными локалями. Для шаблонов Unicode (str) сопоставление с Unicode включено по умолчанию и позволяет обрабатывать разные локали и языки.
Изменено в версии 3.6: Флаг
LOCALEможно использовать только с шаблонами bytes; он несовместим сASCII.Изменено в версии 3.7: Объекты скомпилированных регулярных выражений с флагом
LOCALEбольше не зависят от локали во время компиляции. На результат сопоставления влияет только локаль, действующая в момент сопоставления.
-
re.M -
re.MULTILINE -
Если этот флаг задан, символ шаблона
'^'соответствует началу строки и началу каждой строки текста (сразу после каждого символа новой строки); символ шаблона'$'соответствует концу строки и концу каждой строки текста (сразу перед каждым символом новой строки). По умолчанию'^'соответствует только началу строки, а'$'— только концу строки и непосредственно перед символом новой строки (если он есть) в конце строки.Соответствует встроенному флагу
(?m).
-
re.NOFLAG -
Указывает, что флаги не применяются; значение —
0. Этот флаг можно использовать как значение по умолчанию для именованного аргумента функции или как базовое значение, к которому условно добавляются побитовой операцией ИЛИ другие флаги. Пример использования в качестве значения по умолчанию:def myfunc(text, flag=re.NOFLAG): return re.match(text, flag)Добавлено в версии 3.11.
-
re.S -
re.DOTALL -
Заставляет специальный символ
'.'соответствовать любому символу, включая символ новой строки; без этого флага'.'соответствует любому символу, кроме символа новой строки.Соответствует встроенному флагу
(?s).
-
re.U -
re.UNICODE -
В Python 3 для шаблонов
strпо умолчанию сопоставляются символы Unicode. Поэтому этот флаг избыточен, не имеет эффекта и сохранён только для обратной совместимости.См.
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) -
Просматривает string в поисках первого места, в котором регулярное выражение pattern находит соответствие, и возвращает соответствующий объект
Match. ВозвращаетNone, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это не то же самое, что найти в какой-либо позиции строки соответствие нулевой длины.Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией ИЛИ (оператор
|).
-
re.match(pattern, string, flags=0) -
Если ноль или более символов в начале string соответствуют регулярному выражению pattern, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это не то же самое, что соответствие нулевой длины.Обратите внимание: даже в режиме
MULTILINEфункцияre.match()сопоставляет только с началом строки, а не с началом каждой строки текста.Чтобы найти соответствие в любом месте string, используйте вместо этого
search()(см. также search() и match()).Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией ИЛИ (оператор
|).
-
re.fullmatch(pattern, string, flags=0) -
Если вся строка string соответствует регулярному выражению pattern, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это не то же самое, что соответствие нулевой длины.Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией ИЛИ (оператор
|).Добавлено в версии 3.4.
-
re.split(pattern, string, maxsplit=0, flags=0) -
Разбивает string по вхождениям pattern. Если в pattern используются захватывающие скобки, текст всех групп шаблона также включается в результирующий список. Если maxsplit не равен нулю, выполняется не более maxsplit разбиений, а остаток строки возвращается как последний элемент списка.
>>> re.split(r'\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split(r'\W+', 'Words, words, words.', 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) -
Возвращает все неперекрывающиеся соответствия pattern в string в виде списка строк или кортежей. Строка string просматривается слева направо, а соответствия возвращаются в порядке обнаружения. Пустые соответствия включаются в результат.
Результат зависит от числа захватывающих групп в шаблоне. Если групп нет, возвращается список строк, соответствующих всему шаблону. Если группа ровно одна, возвращается список строк, соответствующих этой группе. Если групп несколько, возвращается список кортежей строк, соответствующих группам. Незахватывающие группы не влияют на форму результата.
>>> 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для всех неперекрывающихся соответствий регулярного выражения pattern в string. Строка string просматривается слева направо, а соответствия возвращаются в порядке обнаружения. Пустые соответствия включаются в результат.Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией ИЛИ (оператор
|).Изменено в версии 3.7: Непустые соответствия теперь могут начинаться сразу после предыдущего пустого соответствия.
-
re.sub(pattern, repl, string, count=0, flags=0) -
Возвращает строку, полученную заменой самых левых неперекрывающихся вхождений pattern в string на замену repl. Если шаблон не найден, string возвращается без изменений. repl может быть строкой или функцией; если это строка, все обратные косые черты в ней обрабатываются как escape-последовательности. То есть
\nпреобразуется в символ новой строки,\r— в возврат каретки и так далее. Неизвестные escape-последовательности с буквами ASCII зарезервированы для будущего использования и считаются ошибками. Другие неизвестные escape-последовательности, такие как\&, остаются без изменений. Обратные ссылки, например\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, помимо описанных выше символьных escape-последовательностей и обратных ссылок,
\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: Неизвестные escape-последовательности в pattern, состоящие из
'\'и буквы ASCII, теперь вызывают ошибки.Изменено в версии 3.7: Неизвестные escape-последовательности в repl, состоящие из
'\'и буквы ASCII, теперь вызывают ошибки.Изменено в версии 3.7: Пустые соответствия шаблону заменяются, если они соседствуют с предыдущим непустым соответствием.
Изменено в версии 3.12: id группы может содержать только цифры ASCII. В строках замены типа
bytesname группы может содержать только байты из диапазона 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) или bytes. См. Тип универсального псевдонима.
-
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) или bytes. См. Тип универсального псевдонима.
-
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) -
Возвращает кортеж, содержащий все подгруппы совпадения: от первой до последней группы в шаблоне. Аргумент 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 возвращает кортеж из двух элементов
(m.start(group), m.end(group)). Обратите внимание: если group не участвовала в совпадении, возвращается(-1, -1). По умолчанию group равен нулю, то есть соответствует всему совпадению.
-
Match.pos -
Значение pos, переданное методу
search()илиmatch()объекта регулярного выражения. Это индекс в строке, с которого механизм регулярных выражений начал поиск совпадения.
-
Match.endpos -
Значение endpos, переданное методу
search()илиmatch()объекта регулярного выражения. Это индекс в строке, за который механизм регулярных выражений не будет заходить.
-
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