Spec-Zone.ru › Python 3.13

re — Операции с регулярными выражениями

Исходный код: Lib/re/

Этот модуль предоставляет операции поиска по регулярным выражениям, аналогичные тем, что есть в Perl.

И шаблоны, и строки для поиска могут быть строками Unicode (str), а также 8-битовыми строками (bytes). Однако строки Unicode и 8-битовые строки нельзя смешивать: то есть нельзя искать соответствие строке Unicode с помощью шаблона bytes или наоборот; аналогично, при запросе замены строка замены должна иметь тот же тип, что и шаблон и строка поиска.

В регулярных выражениях символ обратной косой черты ('\') используется для обозначения специальных форм или для того, чтобы специальные символы можно было использовать без их особого значения. Это противоречит использованию Python того же символа для той же цели в строковых литералах; например, чтобы найти буквальную обратную косую черту, в качестве строки шаблона, возможно, потребуется записать '\\\\', поскольку регулярное выражение должно быть \\, а каждая обратная косая черта внутри обычного строкового литерала Python должна быть представлена как \\. Также обратите внимание, что любые недопустимые escape-последовательности при использовании обратной косой черты в строковых литералах Python теперь вызывают SyntaxWarning, а в будущем это станет SyntaxError. Это поведение проявится, даже если последовательность допустима в регулярном выражении.

Решение — использовать для шаблонов регулярных выражений нотацию сырых строк 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' найдёт два (пустых) совпадения: одно непосредственно перед символом новой строки, а другое — в конце строки.

*

Заставляет полученное регулярное выражение соответствовать 0 или более повторениям предшествующего регулярного выражения, насколько это возможно. ab* будет соответствовать ‘a’, ‘ab’ или ‘a’, за которым следует любое количество символов ‘b’.

+

Заставляет полученное регулярное выражение соответствовать 1 или более повторениям предшествующего регулярного выражения. ab+ будет соответствовать ‘a’, за которым следует любое ненулевое количество символов ‘b’; оно не будет соответствовать одной только ‘a’.

?

Заставляет полученное регулярное выражение соответствовать 0 или 1 повторению предшествующего регулярного выражения. 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-]), он соответствует буквальному символу '-'.
  • Специальные символы, кроме обратной косой черты, теряют своё специальное значение внутри наборов. Например, [(+*)] будет соответствовать любому из буквальных символов '(', '+', '*' или ')'.
  • Обратная косая черта либо экранирует символы, имеющие специальное значение в наборе, например '-', ']', '^' и сам символ '\\', либо обозначает специальную последовательность, представляющую один символ, например \xa0 или \n, либо класс символов, например \w или \S (определённые ниже). Обратите внимание: \b обозначает один символ «забоя», а не границу слова, как вне набора; числовые экранированные последовательности, такие как \1, всегда являются восьмеричными кодами, а не ссылками на группы. Специальные последовательности, которые не соответствуют одному символу, например \A и \Z, не допускаются.
  • Символы, не входящие в диапазон, можно сопоставить, выполнив инвертирование набора. Если первый символ набора — '^', будут сопоставлены все символы, не входящие в набор. Например, [^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}. Обратите внимание: шаблоны, начинающиеся с положительного утверждения просмотра назад, не будут соответствовать в начале искомой строки; скорее всего, вам понадобится функция 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, результирующее регулярное выражение будет соответствовать второму символу. Например, \$ соответствует символу '$'.

\number

Соответствует содержимому группы с таким же номером. Нумерация групп начинается с 1. Например, (.+) \1 соответствует 'the the' или '55 55', но не 'thethe' (обратите внимание на пробел после группы). Эта специальная последовательность позволяет сопоставлять только одну из первых 99 групп. Если первая цифра в number равна 0 или number состоит из 3 восьмеричных цифр, последовательность будет интерпретирована не как ссылка на группу, а как символ с восьмеричным значением number. Внутри '[' и ']' класса символов все числовые экранированные последовательности трактуются как символы.

\A

Соответствует только в начале строки.

\b

Соответствует пустой строке, но только в начале или в конце слова. Слово определяется как последовательность символов слова. Формально \b определяется как граница между символом \w и символом \W (или наоборот), либо между \w и началом или концом строки. Это означает, что r'\bat\b' соответствует 'at', 'at.', '(at)' и 'as at ay', но не 'attempt' и не 'atlas'.

По умолчанию символами слова в шаблонах Unicode (str) являются буквенно-цифровые символы Unicode и подчёркивание, но это можно изменить, используя флаг ASCII. При использовании флага LOCALE границы слов определяются текущей локалью.

Примечание

Внутри диапазона символов \b обозначает символ забоя для совместимости со строковыми литералами Python.

\B

Соответствует пустой строке, но только если она не находится в начале или конце слова. Это означает, что r'at\B' соответствует 'athens', 'atom', 'attorney', но не 'at', 'at.' или 'at!'. \B противоположно \b, поэтому символы слова в шаблонах Unicode (str) — это буквы и цифры Unicode или знак подчёркивания, хотя это можно изменить с помощью флага ASCII. Границы слов определяются текущей локалью, если используется флаг LOCALE.

Примечание

Обратите внимание, что \B не соответствует пустой строке, в отличие от реализаций регулярных выражений в других языках программирования, например Perl. Это поведение сохранено для обеспечения совместимости.

\d
Для шаблонов Unicode (str):

Соответствует любой десятичной цифре Unicode (то есть любому символу из категории символов Unicode [Nd]). Сюда входит [0-9], а также множество других символов-цифр.

Соответствует [0-9], если используется флаг ASCII.

Для 8-битных шаблонов (bytes):

Соответствует любой десятичной цифре из набора символов ASCII; это эквивалентно [0-9].

\D

Соответствует любому символу, который не является десятичной цифрой. Это противоположность \d.

Соответствует [^0-9], если используется флаг ASCII.

\s
Для шаблонов Unicode (str):

Соответствует пробельным символам Unicode (как определено в str.isspace()). Сюда входит [ \t\n\r\f\v], а также множество других символов, например неразрывные пробелы, предписанные правилами типографики во многих языках.

Соответствует [ \t\n\r\f\v], если используется флаг ASCII.

Для 8-битных шаблонов (bytes):

Соответствует символам, которые считаются пробельными в наборе символов ASCII; это эквивалентно [ \t\n\r\f\v].

\S

Соответствует любому символу, который не является пробельным. Это противоположность \s.

Соответствует [^ \t\n\r\f\v], если используется флаг ASCII.

\w
Для шаблонов Unicode (str):

Соответствует символам слова Unicode; сюда входят все буквенно-цифровые символы Unicode (как определено в str.isalnum()), а также знак подчёркивания (_).

Соответствует [a-zA-Z0-9_], если используется флаг ASCII.

Для 8-битных шаблонов (bytes):

Соответствует символам, которые считаются буквенно-цифровыми в наборе символов ASCII; это эквивалентно [a-zA-Z0-9_]. Если используется флаг LOCALE, соответствуют символы, которые считаются буквенно-цифровыми в текущей локали, а также знак подчёркивания.

\W

Соответствует любому символу, который не является символом слова. Это противоположность \w. По умолчанию соответствует символам, не являющимся знаком подчёркивания (_), для которых str.isalnum() возвращает False.

Соответствует [^a-zA-Z0-9_], если используется флаг ASCII.

Если используется флаг LOCALE, соответствуют символы, которые в текущей локали не являются ни буквенно-цифровыми, ни знаком подчёркивания.

\Z

Соответствует только в конце строки.

Большинство последовательностей экранирования, поддерживаемых строковыми литералами Python, также распознаются анализатором регулярных выражений:

\a      \b      \f      \n
\N      \r      \t      \u
\U      \v      \x      \\

(Обратите внимание, что \b используется для обозначения границ слов и означает «возврат на одну позицию» только внутри символьных классов.)

Последовательности экранирования '\u', '\U' и '\N' распознаются только в шаблонах Unicode (str). В шаблонах bytes они считаются ошибками. Неизвестные последовательности экранирования с буквами ASCII зарезервированы для будущего использования и считаются ошибками.

Восьмеричные последовательности экранирования поддерживаются в ограниченном виде. Если первая цифра — 0 или указаны три восьмеричные цифры, последовательность считается восьмеричной. В противном случае это ссылка на группу. Как и в строковых литералах, длина восьмеричных последовательностей экранирования не превышает трёх цифр.

Изменено в версии 3.3: Добавлены последовательности экранирования '\u' и '\U'.

Изменено в версии 3.6: Неизвестные последовательности экранирования, состоящие из '\' и буквы ASCII, теперь считаются ошибками.

Изменено в версии 3.8: Добавлена последовательность экранирования '\N{name}'. Как и в строковых литералах, она подставляет именованный символ Unicode (например, '\N{EM DASH}').

Содержимое модуля

Модуль определяет несколько функций, констант и исключение. Некоторые функции представляют собой упрощённые версии полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используют скомпилированную форму.

Флаги

Изменено в версии 3.6: Константы флагов теперь являются экземплярами RegexFlag, который является подклассом enum.IntFlag.

class re.RegexFlag

Класс enum.IntFlag, содержащий перечисленные ниже параметры регулярных выражений.

Добавлено в версии 3.11: - добавлено в __all__

re.A
re.ASCII

Заставляет \w, \W, \b, \B, \d, \D, \s и \S выполнять поиск только по ASCII, а не по всему диапазону Unicode. Это имеет смысл только для шаблонов Unicode (str); для шаблонов bytes флаг игнорируется.

Соответствует встроенному флагу (?a).

Примечание

Флаг U по-прежнему существует для обратной совместимости, но в Python 3 он избыточен, поскольку для шаблонов str сопоставление по умолчанию выполняется с учётом Unicode, а для шаблонов bytes сопоставление с учётом Unicode недопустимо. UNICODE и встроенный флаг (?u) аналогично избыточны.

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 (str) сопоставление с учётом Unicode включено по умолчанию, и оно поддерживает разные локали и языки.

Изменено в версии 3.6: LOCALE можно использовать только с шаблонами bytes, и он несовместим с ASCII.

Изменено в версии 3.7: Объекты скомпилированных регулярных выражений с флагом LOCALE больше не зависят от локали на этапе компиляции. На результат сопоставления влияет только локаль на момент сопоставления.

re.M
re.MULTILINE

Если указан этот флаг, символ шаблона '^' соответствует началу строки и началу каждой строки текста (сразу после каждого символа новой строки); символ шаблона '$' соответствует концу строки и концу каждой строки текста (непосредственно перед каждым символом новой строки). По умолчанию '^' соответствует только началу строки, а '$' — только концу строки и непосредственно перед символом новой строки (если он есть) в конце строки.

Соответствует встроенному флагу (?m).

re.NOFLAG

Указывает, что флаги не применяются; значение равно 0. Этот флаг можно использовать как значение по умолчанию для именованного аргумента функции или как базовое значение, которое при необходимости объединяется с другими флагами операцией OR. Пример использования в качестве значения по умолчанию:

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. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

Последовательность

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. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

re.match(pattern, string, flags=0)

Если ноль или более символов в начале string соответствуют регулярному выражению pattern, возвращает соответствующий объект Match. Возвращает None, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.

Обратите внимание: даже в режиме MULTILINE функция re.match() сопоставляет только начало строки, а не начало каждой строки текста.

Чтобы найти совпадение в любом месте string, используйте search() (см. также search() и match()).

Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

re.fullmatch(pattern, string, flags=0)

Если вся строка string соответствует регулярному выражению pattern, возвращает соответствующий объект Match. Возвращает None, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.

Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

Добавлено в версии 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.', maxsplit=1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

Если разделитель содержит захватывающие группы и совпадает с началом строки, результат будет начинаться с пустой строки. То же относится к концу строки:

>>> re.split(r'(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

Благодаря этому компоненты разделителя всегда находятся по одним и тем же относительным индексам в результирующем списке.

Соседние пустые совпадения невозможны, но пустое совпадение может возникнуть сразу после непустого.

>>> re.split(r'\b', 'Words, words, words.')
['', 'Words', ', ', 'words', ', ', 'words', '.']
>>> re.split(r'\W*', '...words...')
['', '', 'w', 'o', 'r', 'd', 's', '', '']
>>> re.split(r'(\W*)', '...words...')
['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']

Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

Изменено в версии 3.1: Добавлен необязательный аргумент flags.

Изменено в версии 3.7: Добавлена поддержка разделения по шаблону, который может соответствовать пустой строке.

Устарело с версии 3.13: Передача maxsplit и flags в качестве позиционных аргументов устарела. В будущих версиях Python они будут параметрами, доступными только по ключевому слову.

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. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

Изменено в версии 3.7: Теперь непустые совпадения могут начинаться сразу после предыдущего пустого совпадения.

re.finditer(pattern, string, flags=0)

Возвращает итератор, выдающий объекты Match для всех неперекрывающихся совпадений шаблона RE pattern в string. Строка string просматривается слева направо, а совпадения возвращаются в порядке обнаружения. Пустые совпадения включаются в результат.

Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

Изменено в версии 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-' вместо '-a-b-d-'.

В строковых аргументах repl, помимо описанных выше экранирующих последовательностей и обратных ссылок, \g<name> использует подстроку, соответствующую группе с именем name, определённой синтаксисом (?P<name>...). \g<number> использует соответствующий номер группы; поэтому \g<2> эквивалентно \2, но не вызывает неоднозначности в такой замене, как \g<2>0. \20 будет интерпретировано как ссылка на группу 20, а не как ссылка на группу 2 с последующим буквальным символом '0'. Обратная ссылка \g<0> подставляет всю подстроку, соответствующую RE.

Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

Изменено в версии 3.1: Добавлен необязательный аргумент flags.

Изменено в версии 3.5: Несопоставленные группы заменяются пустой строкой.

Изменено в версии 3.6: Неизвестные экранирующие последовательности в pattern, состоящие из '\' и буквы ASCII, теперь считаются ошибками.

Изменено в версии 3.7: Неизвестные экранирующие последовательности в repl, состоящие из '\' и буквы ASCII, теперь считаются ошибками. Пустое совпадение может возникнуть сразу после непустого.

Изменено в версии 3.12: id группы может содержать только цифры ASCII. В строках замены bytes name группы может содержать только байты из диапазона ASCII (b'\x00'–b'\x7f').

Устарело с версии 3.13: Передача count и flags в качестве позиционных аргументов устарела. В будущих версиях Python они будут параметрами, доступными только по ключевому слову.

re.subn(pattern, repl, string, count=0, flags=0)

Выполняет ту же операцию, что и sub(), но возвращает кортеж (new_string, number_of_subs_made).

Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные флагов, объединённые побитовой операцией OR (оператор |).

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.PatternError(msg, pattern=None, pos=None)

Исключение, возникающее, когда строка, переданная одной из описанных здесь функций, не является допустимым регулярным выражением (например, в ней могут быть несбалансированные скобки) или когда во время компиляции либо сопоставления происходит другая ошибка. Отсутствие в строке совпадений с шаблоном никогда не считается ошибкой. Экземпляр PatternError имеет следующие дополнительные атрибуты:

msg

Неформатированное сообщение об ошибке.

pattern

Шаблон регулярного выражения.

pos

Индекс в pattern, на котором произошёл сбой компиляции (может быть равен None).

lineno

Номер строки, соответствующий pos (может быть равен None).

colno

Номер столбца, соответствующий pos (может быть равен None).

Изменено в версии 3.5: Добавлены дополнительные атрибуты.

Изменено в версии 3.13: Изначально PatternError называлось error; последнее имя сохранено как псевдоним для обратной совместимости.

Объекты регулярных выражений

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 возвращает 2-кортеж (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() которого создал этот экземпляр совпадения.

Match.string

Строка, переданная методу 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() и регулярными выражениями.

Маркер scanf()

Регулярное выражение

%c

.

%5c

.{5}

%d

[-+]?\d+

%e, %E, %f, %g

[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?

%i

[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)

%o

[-+]?[0-7]+

%s

\S+

%u

\d+

%x, %X

[-+]?(0[xX])?[\dA-Fa-f]+

Чтобы извлечь имя файла и числа из строки вида

/usr/sbin/sendmail - 0 errors, 4 warnings

можно использовать формат scanf(), например:

%s - %d errors, %d warnings

Эквивалентное регулярное выражение:

(\S+) - (\d+) errors, (\d+) warnings

search() и match()

В Python предусмотрены разные базовые операции с регулярными выражениями:

  • re.match() проверяет совпадение только в начале строки
  • re.search() проверяет совпадение в любом месте строки (таково поведение Perl по умолчанию)
  • re.fullmatch() проверяет, совпадает ли вся строка целиком

Например:

>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # Match
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # No match

Регулярные выражения, начинающиеся с '^', можно использовать с search(), чтобы ограничить совпадение началом строки:

>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<re.Match object; span=(0, 1), match='a'>

Однако обратите внимание, что в режиме MULTILINE функция match() ищет совпадение только в начале строки, тогда как search() с регулярным выражением, начинающимся с '^', будет искать совпадение в начале каждой строки.

>>> re.match("X", "A\nB\nX", re.MULTILINE)  # No match
>>> re.search("^X", "A\nB\nX", re.MULTILINE)  # Match
<re.Match object; span=(4, 5), match='X'>

Создание телефонного справочника

split() разбивает строку на список, разделяя её по заданному шаблону. Этот метод незаменим при преобразовании текстовых данных в структуры данных, которые Python может легко обрабатывать и изменять, как показано в следующем примере создания телефонного справочника.

Сначала рассмотрим входные данные. Обычно они могут поступать из файла, но здесь используется синтаксис строк в тройных кавычках:

>>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""

Записи разделены одной или несколькими строками. Теперь преобразуем строку в список, где каждой непустой строке соответствует отдельная запись:

>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']

Наконец, разделим каждую запись на список, содержащий имя, фамилию, номер телефона и адрес. Используем параметр maxsplit функции split(), поскольку адрес содержит пробелы, входящие в шаблон разделения:

>>> [re.split(":? ", entry, maxsplit=3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]

Шаблон :? совпадает с двоеточием после фамилии, поэтому оно не попадает в результирующий список. Если установить maxsplit равным 4, можно отделить номер дома от названия улицы:

>>> [re.split(":? ", entry, maxsplit=4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]

Преобразование текста

sub() заменяет каждое вхождение шаблона строкой или результатом вызова функции. В этом примере показано, как с помощью sub() и функции «искажать» текст, то есть случайным образом переставлять символы в каждом слове предложения, кроме первого и последнего:

>>> def repl(m):
...     inner_word = list(m.group(2))
...     random.shuffle(inner_word)
...     return m.group(1) + "".join(inner_word) + m.group(3)
...
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'

Поиск всех наречий

findall() находит все вхождения шаблона, а не только первое, как это делает search(). Например, если автор хочет найти в тексте все наречия, он может использовать findall() следующим образом:

>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly\b", text)
['carefully', 'quickly']

Поиск всех наречий и их позиций

Если нужно получить о совпадениях шаблона больше сведений, чем просто совпавший текст, полезна функция finditer(), поскольку она возвращает объекты Match, а не строки. Продолжая предыдущий пример: если автор хочет найти в тексте все наречия и их позиции, он может использовать finditer() следующим образом:

>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
...     print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly

Обозначение сырых строк

Обозначение сырых строк (r"text") упрощает работу с регулярными выражениями. Без него каждую обратную косую черту ('\') в регулярном выражении пришлось бы предварять ещё одной, чтобы экранировать её. Например, следующие две строки кода функционально эквивалентны:

>>> re.match(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>

Чтобы найти буквальную обратную косую черту, её нужно экранировать в регулярном выражении. При использовании обозначения сырых строк это означает r"\\". Без обозначения сырых строк нужно использовать "\\\\", поэтому следующие строки кода функционально эквивалентны:

>>> re.match(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>

Написание токенизатора

Токенизатор или сканер анализирует строку и классифицирует группы символов. Это полезный первый шаг при написании компилятора или интерпретатора.

Категории текста задаются регулярными выражениями. Метод заключается в том, чтобы объединить их в одно главное регулярное выражение и выполнять цикл по последовательно найденным совпадениям:

from typing import NamedTuple
import re

class Token(NamedTuple):
    type: str
    value: str
    line: int
    column: int

def tokenize(code):
    keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
    token_specification = [
        ('NUMBER',   r'\d+(\.\d*)?'),  # Integer or decimal number
        ('ASSIGN',   r':='),           # Assignment operator
        ('END',      r';'),            # Statement terminator
        ('ID',       r'[A-Za-z]+'),    # Identifiers
        ('OP',       r'[+\-*/]'),      # Arithmetic operators
        ('NEWLINE',  r'\n'),           # Line endings
        ('SKIP',     r'[ \t]+'),       # Skip over spaces and tabs
        ('MISMATCH', r'.'),            # Any other character
    ]
    tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
    line_num = 1
    line_start = 0
    for mo in re.finditer(tok_regex, code):
        kind = mo.lastgroup
        value = mo.group()
        column = mo.start() - line_start
        if kind == 'NUMBER':
            value = float(value) if '.' in value else int(value)
        elif kind == 'ID' and value in keywords:
            kind = value
        elif kind == 'NEWLINE':
            line_start = mo.end()
            line_num += 1
            continue
        elif kind == 'SKIP':
            continue
        elif kind == 'MISMATCH':
            raise RuntimeError(f'{value!r} unexpected on line {line_num}')
        yield Token(kind, value, line_num, column)

statements = '''
    IF quantity THEN
        total := total + price * quantity;
        tax := price * 0.05;
    ENDIF;
'''

for token in tokenize(statements):
    print(token)

Токенизатор выдаёт следующий результат:

Token(type='IF', value='IF', line=2, column=4)
Token(type='ID', value='quantity', line=2, column=7)
Token(type='THEN', value='THEN', line=2, column=16)
Token(type='ID', value='total', line=3, column=8)
Token(type='ASSIGN', value=':=', line=3, column=14)
Token(type='ID', value='total', line=3, column=17)
Token(type='OP', value='+', line=3, column=23)
Token(type='ID', value='price', line=3, column=25)
Token(type='OP', value='*', line=3, column=31)
Token(type='ID', value='quantity', line=3, column=33)
Token(type='END', value=';', line=3, column=41)
Token(type='ID', value='tax', line=4, column=8)
Token(type='ASSIGN', value=':=', line=4, column=12)
Token(type='ID', value='price', line=4, column=15)
Token(type='OP', value='*', line=4, column=21)
Token(type='NUMBER', value=0.05, line=4, column=23)
Token(type='END', value=';', line=4, column=27)
Token(type='ENDIF', value='ENDIF', line=5, column=4)
Token(type='END', value=';', line=5, column=9)
[Frie09]

Фридл, Джеффри. Освоение регулярных выражений. 3-е изд., O’Reilly Media, 2009. Третье издание книги уже совсем не рассматривает Python, однако в первом издании подробно описано, как составлять качественные шаблоны регулярных выражений.

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/re.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API