re.md
1> **Источник:** https://python-all.ru/3.16/library/re.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `re` – Операции с регулярными выражениями89**Исходный код:** [Lib/re/](https://python-all.ru/src/main/Lib/re)1011---1213Этот модуль предоставляет операции сопоставления с регулярными выражениями, аналогичные тем, что есть в Perl.1415И шаблоны, и строки для поиска могут быть строками Unicode ([`str`](https://python-all.ru/3.16/library/stdtypes.html#str)), а также 8-битными строками ([`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes)). Однако строки Unicode и 8-битные строки нельзя смешивать: то есть нельзя сопоставить строку Unicode с шаблоном bytes или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон, и искомая строка.1617Регулярные выражения используют символ обратной косой черты (`'\'`) для обозначения специальных форм или для использования специальных символов без вызова их специального значения. Это конфликтует с использованием того же символа в Python для той же цели в строковых литералах; например, для сопоставления буквальной обратной косой черты может потребоваться написать `'\\\\'` как шаблонную строку, потому что регулярное выражение должно быть `\\`, и каждая обратная косая черта должна быть выражена как `\\` внутри обычного строкового литерала Python. Также обратите внимание, что любые недопустимые escape-последовательности при использовании обратной косой черты в строковых литералах Python теперь порождают [`SyntaxWarning`](https://python-all.ru/3.16/library/exceptions.html#SyntaxWarning) и в будущем это станет [`SyntaxError`](https://python-all.ru/3.16/library/exceptions.html#SyntaxError). Это поведение будет иметь место, даже если это допустимая escape-последовательность для регулярного выражения.1819Решение – использовать сырые строки Python для шаблонов регулярных выражений; обратные косые черты не обрабатываются особым образом в строковых литералах с префиксом `'r'`. Таким образом, `r"\n"` – это строка из двух символов, содержащая `'\'` и `'n'`, тогда как `"\n"` – это строка из одного символа, содержащая символ новой строки. Обычно шаблоны выражаются в коде Python с использованием этой нотации сырых строк.2021Важно отметить, что большинство операций с регулярными выражениями доступны как функции уровня модуля и методы [скомпилированных регулярных выражений](https://python-all.ru/3.16/library/re.html#re-objects). Функции – это ярлыки, которые не требуют предварительной компиляции объекта regex, но не имеют некоторых параметров тонкой настройки.2223> **См. также**24>25> Сторонний модуль [regex](https://python-all.ru/3.16/library/re.html), API которого совместим с модулем стандартной библиотеки `re`, но предлагает дополнительные функции и более полную поддержку Unicode.2627## Синтаксис регулярных выражений2829Регулярное выражение (или RE) задаёт набор строк, которым оно соответствует; функции в этом модуле позволяют проверить, соответствует ли конкретная строка заданному регулярному выражению (или соответствует ли заданное регулярное выражение конкретной строке – что одно и то же).3031Регулярные выражения можно объединять для получения новых регулярных выражений; если *A* и *B* – оба регулярные выражения, то *AB* тоже является регулярным выражением. В общем, если строка *p* соответствует *A*, а другая строка *q* соответствует *B*, то строка *pq* будет соответствовать AB. Это верно, если только *A* или *B* не содержат операций с низким приоритетом; граничных условий между *A* и *B*; или нумерованных ссылок на группы. Таким образом, сложные выражения легко строятся из более простых примитивных выражений, подобных описанным здесь. Подробности теории и реализации регулярных выражений можно найти в книге Фридла [\[Frie09\]](https://python-all.ru/3.16/library/re.html#frie09), или почти в любом учебнике по конструированию компиляторов.3233Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более мягкого изложения обратитесь к [Regular expression HOWTO](https://python-all.ru/3.16/howto/regex.html#regex-howto).3435Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, например `'A'`, `'a'` или `'0'`, являются простейшими регулярными выражениями; они просто соответствуют сами себе. Можно объединять обычные символы, поэтому `last` соответствует строке `'last'`. (В оставшейся части этого раздела мы будем записывать RE в `this special style`, обычно без кавычек, а строки для сопоставления – в `'in single quotes'`.)3637Некоторые символы, например `'|'` или `'('`, являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на интерпретацию окружающих их регулярных выражений.3839Операторы повторения или квантификаторы (`*`, `+`, `?`, `{m,n}` и т.д.) не могут быть вложены напрямую. Это позволяет избежать неоднозначности с суффиксом нежадного модификатора `?` и с другими модификаторами в других реализациях. Чтобы применить второе повторение к внутреннему повторению, можно использовать круглые скобки. Например, выражение `(?:a{6})*` соответствует любому количеству, кратному шести, символов `'a'`.4041Специальные символы:4243**`.`**4445(Точка.) В режиме по умолчанию соответствует любому символу, кроме символа новой строки. Если указан флаг [`DOTALL`](https://python-all.ru/3.16/library/re.html#re.DOTALL), соответствует любому символу, включая символ новой строки. `(?s:.)` соответствует любому символу независимо от флагов.4647**`^`**4849(Циркумфлекс.) Соответствует началу строки, а в режиме [`MULTILINE`](https://python-all.ru/3.16/library/re.html#re.MULTILINE) также соответствует сразу после каждого символа новой строки.5051**`$`**5253Соответствует концу строки или непосредственно перед символом новой строки в конце строки, а в режиме [`MULTILINE`](https://python-all.ru/3.16/library/re.html#re.MULTILINE) также соответствует перед символом новой строки. `foo` соответствует и ‘foo’, и ‘foobar’, в то время как регулярное выражение `foo$` соответствует только ‘foo’. Интереснее то, что поиск `foo.$` в `'foo1\nfoo2\n'` обычно соответствует ‘foo2’, но в режиме `MULTILINE` – ‘foo1’; поиск одиночного `$` в `'foo\n'` найдет два (пустых) совпадения: одно сразу перед символом новой строки, и одно в конце строки.5455**`*`**5657Заставляет результирующее RE соответствовать 0 или более повторениям предыдущего RE, насколько это возможно. `ab*` будет соответствовать ‘a’, ‘ab’ или ‘a’, за которым следует любое количество символов ‘b’.5859**`+`**6061Заставляет результирующее RE соответствовать 1 или более повторениям предыдущего RE. `ab+` будет соответствовать ‘a’, за которым следует любое ненулевое количество символов ‘b’; оно не будет соответствовать просто ‘a’.6263**`?`**6465Заставляет результирующее RE соответствовать 0 или 1 повторению предыдущего RE. `ab?` будет соответствовать либо ‘a’, либо ‘ab’.6667**`*?`, `+?`, `??`**6869Квантификаторы `'*'`, `'+'` и `'?'` являются *жадными*; они сопоставляют как можно больше текста. Иногда такое поведение нежелательно; если RE `<.*>` сопоставляется с `'<a> b <c>'`, оно будет соответствовать всей строке, а не только `'<a>'`. Добавление `?` после квантификатора заставляет его выполнять сопоставление в *нежадном* или *минимальном* режиме; будет сопоставлено как можно *меньше* символов. Использование RE `<.*?>` будет соответствовать только `'<a>'`.7071**`*+`, `++`, `?+`**7273Как и квантификаторы `'*'`, `'+'` и `'?'`, те, к которым добавлен `'+'`, также сопоставляются как можно больше раз. Однако, в отличие от истинно жадных квантификаторов, они не допускают возврата, когда следующее за ними выражение не совпадает. Они известны как *притяжательные* квантификаторы. Например, `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?)`.7475Добавлено в версии 3.12.7677**`{m}`**7879Указывает, что должно быть сопоставлено ровно *m* копий предыдущего RE; меньшее количество совпадений приводит к тому, что всё RE не соответствует. Например, `a{6}` будет соответствовать ровно шести символам `'a'`, но не пяти.8081**`{m,n}`**8283Заставляет результирующее RE соответствовать от *m* до *n* повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например, `a{3,5}` будет соответствовать от 3 до 5 символов `'a'`. Пропуск *m* задаёт нижнюю границу, равную нулю, а пропуск *n* задаёт бесконечную верхнюю границу. В качестве примера, `a{4,}b` будет соответствовать `'aaaab'` или тысяче символов `'a'`, за которыми следует `'b'`, но не `'aaab'`. Запятую нельзя опускать, иначе модификатор будет спутан с ранее описанной формой.8485**`{m,n}?`**8687Заставляет результирующее RE соответствовать от *m* до *n* повторений предыдущего RE, пытаясь сопоставить как можно *меньше* повторений. Это нежадная версия предыдущего квантификатора. Например, для строки из 6 символов `'aaaaaa'`, `a{3,5}` будет соответствовать 5 символам `'a'`, в то время как `a{3,5}?` будет соответствовать только 3 символам.8889**`{m,n}+`**9091Заставляет результирующее регулярное выражение соответствовать от *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})`.9293Добавлено в версии 3.12.9495**`\`**9697Либо экранирует специальные символы (позволяя сопоставлять такие символы, как `'*'`, `'?'` и т.д.), либо обозначает специальную последовательность; специальные последовательности рассматриваются ниже.9899Если вы не используете сырую строку для выражения шаблона, помните, что Python также использует обратную косую черту как escape-последовательность в строковых литералах; если escape- последовательность не распознаётся парсером Python, обратная косая черта и следующий за ней символ включаются в результирующую строку. Однако если Python распознает результирующую последовательность, обратную косую черту следует удвоить. Это сложно и трудно для понимания, поэтому настоятельно рекомендуется использовать сырые строки для всех, кроме самых простых выражений.100101**`[]`**102103Используется для обозначения набора символов. В наборе:104105- Символы можно перечислять по отдельности, например, `[amk]` совпадет с `'a'`, `'m'` или `'k'`.106107- Диапазоны символов можно указать, задав два символа и разделив их `'-'`, например `[a-z]` совпадет с любой строчной буквой ASCII, `[0-5][0-9]` – со всеми двузначными числами от `00` до `59`, а `[0-9A-Fa-f]` – с любой шестнадцатеричной цифрой. Если `-` экранирован (например, `[a\-z]`) или стоит первым или последним символом (например, `[-a]` или `[a-]`), он будет совпадать с литералом `'-'`.108- Специальные символы, кроме обратной косой черты, теряют своё специальное значение внутри наборов. Например, `[(+*)]` совпадет с любым из литеральных символов `'('`, `'+'`, `'*'` или `')'`.109110- Обратная косая черта либо экранирует символы, имеющие специальное значение в наборе, такие как `'-'`, `']'`, `'^'` и сама `'\\'`, либо обозначает специальную последовательность, представляющую один символ, например `\xa0` или `\n`, или класс символов, такой как `\w` или `\S` (определены ниже). Обратите внимание, что `\b` представляет отдельный символ забоя, а не границу слова, как вне набора, и числовые escape-последовательности, такие как `\1`, всегда являются восьмеричными escape-последовательностями, а не ссылками на группы. Специальные последовательности, не соответствующие одному символу, такие как `\A` и `\z`, не допускаются.111112- Символы, не входящие в диапазон, можно сопоставить с помощью *дополнения* набора. Если первый символ набора – `'^'`, то будут сопоставлены все символы, которые *не* входят в набор. Например, `[^5]` совпадет с любым символом, кроме `'5'`, а `[^^]` – с любым символом, кроме `'^'`. `^` не имеет специального значения, если он не первый символ в наборе.113- Чтобы сопоставить литерал `']'` внутри набора, поставьте перед ним обратную косую черту или поместите его в начало набора. Например, оба `[()[\]{}]` и `[]()[{}]` совпадут с правой квадратной скобкой, а также с левой квадратной скобкой, фигурными скобками и круглыми скобками.114115- Набор символов может содержать вложенный набор, записанный в квадратных скобках, и два набора можно объединить с помощью оператора набора, как в [Unicode Technical Standard #18](https://python-all.ru/3.16/library/re.html):116117 - `[A--B]` (*разность*) соответствует символу, который входит в *A*, но не входит в *B*; например `[a-z--[aeiou]]` соответствует строчной согласной букве ASCII.118 - `[A&&B]` (*пересечение*) соответствует символу, который входит как в *A*, так и в *B*; например `[\w&&[a-z]]` соответствует строчной букве ASCII.119 - `[A||B]` (*объединение*) соответствует символу, который входит в *A* или в *B*; это то же самое, что перечислить элементы обоих наборов в одном наборе, но позволяет объединять вложенные наборы.120121 Операторы не имеют приоритета и применяются слева направо. Для группировки запишите вложенный набор как операнд после оператора, например `[a-z--[aeiou]]`. Начальный `'^'` инвертирует весь результат. `'['` начинает вложенный набор только сразу после оператора набора; в любом другом месте – включая начало набора символов – это обычный символ, поэтому существующие шаблоны сохраняют своё значение. Экранируется как `'\['`, чтобы включить литерал `'['` сразу после оператора.122123> **Примечание**124>125> Симметричная разность (`A~~B`) пока не поддерживается; литерал `'~~'` в наборе символов по-прежнему вызывает [`FutureWarning`](https://python-all.ru/3.16/library/exceptions.html#FutureWarning).126127Изменено в версии 3.7: [`FutureWarning`](https://python-all.ru/3.16/library/exceptions.html#FutureWarning) вызывается, если набор символов содержит конструкции, которые в будущем изменят семантику.128129Изменено в версии 3.16.0a0 (не выпущена): Добавлена поддержка вложенных наборов и операторов набора `--`, `&&` и `||`.130131**`|`**132133`A|B`, где *A* и *B* могут быть произвольными РВ, создаёт регулярное выражение, которое совпадает либо с *A*, либо с *B*. Таким образом можно разделить произвольное количество РВ с помощью `'|'`. Это также можно использовать внутри групп (см. ниже). По мере сканирования целевой строки РВ, разделённые `'|'`, пробуются слева направо. Когда один шаблон полностью совпадает, эта ветвь принимается. Это означает, что как только *A* совпадает, *B* больше не проверяется, даже если бы оно дало более длинное общее совпадение. Другими словами, оператор `'|'` никогда не является жадным. Чтобы сопоставить литерал `'|'`, используйте `\|` или заключите его в класс символов, например `[|]`.134135**`(...)`**136137Соответствует любому регулярному выражению внутри круглых скобок и обозначает начало и конец группы; содержимое группы можно получить после выполнения сопоставления, а также сопоставить позже в строке с помощью специальной последовательности `\number`, описанной ниже. Чтобы сопоставить литералы `'('` или `')'`, используйте `\(` или `\)` или заключите их в класс символов: `[(]`, `[)]`.138139**`(?...)`**140141Это расширенная запись (иначе `'?'` после `'('` не имеет смысла). Первый символ после `'?'` определяет значение и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу; `(?P<name>...)` – единственное исключение из этого правила. Ниже перечислены поддерживаемые в настоящее время расширения.142143**`(?aiLmsux)`**144145(Одна или несколько букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`.) Группа соответствует пустой строке; буквы устанавливают соответствующие флаги для всего регулярного выражения:146147- [`re.A`](https://python-all.ru/3.16/library/re.html#re.A) (только ASCII)148- [`re.I`](https://python-all.ru/3.16/library/re.html#re.I) (без учёта регистра)149- [`re.L`](https://python-all.ru/3.16/library/re.html#re.L) (зависит от локали)150- [`re.M`](https://python-all.ru/3.16/library/re.html#re.M) (многострочный режим)151- [`re.S`](https://python-all.ru/3.16/library/re.html#re.S) (точка совпадает со всем)152- [`re.U`](https://python-all.ru/3.16/library/re.html#re.U) (сопоставление Unicode)153- [`re.X`](https://python-all.ru/3.16/library/re.html#re.X) (подробный режим)154155(Флаги описаны в разделе [Содержимое модуля](https://python-all.ru/3.16/library/re.html#contents-of-module-re).) Это полезно, если требуется включить флаги как часть регулярного выражения, вместо передачи аргумента *flag* в функцию [`re.compile()`](https://python-all.ru/3.16/library/re.html#re.compile). Флаги должны использоваться первыми в строке выражения.156157Изменено в версии 3.11: Эту конструкцию можно использовать только в начале выражения.158159**`(?:...)`**160161Незапоминающая версия обычных круглых скобок. Совпадает с любым регулярным выражением внутри скобок, но подстрока, совпавшая с группой, *не может* быть извлечена после выполнения сопоставления или использована для ссылки позже в шаблоне.162163**`(?aiLmsux-imsx:...)`**164165(Ноль или более букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`, за которыми необязательно следует `'-'`, а затем одна или несколько букв из `'i'`, `'m'`, `'s'`, `'x'`.) Буквы устанавливают или снимают соответствующие флаги для части выражения:166167- [`re.A`](https://python-all.ru/3.16/library/re.html#re.A) (только ASCII)168- [`re.I`](https://python-all.ru/3.16/library/re.html#re.I) (без учёта регистра)169- [`re.L`](https://python-all.ru/3.16/library/re.html#re.L) (зависит от локали)170- [`re.M`](https://python-all.ru/3.16/library/re.html#re.M) (многострочный режим)171- [`re.S`](https://python-all.ru/3.16/library/re.html#re.S) (точка совпадает со всем)172- [`re.U`](https://python-all.ru/3.16/library/re.html#re.U) (сопоставление Unicode)173- [`re.X`](https://python-all.ru/3.16/library/re.html#re.X) (подробный режим)174175(Флаги описаны в разделе [Содержимое модуля](https://python-all.ru/3.16/library/re.html#contents-of-module-re).)176177Буквы `'a'`, `'L'` и `'u'` являются взаимоисключающими при использовании в качестве встроенных флагов, поэтому их нельзя комбинировать или помещать после `'-'`. Вместо этого, когда одна из них появляется во встроенной группе, она переопределяет режим сопоставления в объемлющей группе. В шаблонах Unicode `(?a:...)` переключает на сопоставление только ASCII, а `(?u:...)` переключает на сопоставление Unicode (по умолчанию). В шаблонах байтов `(?L:...)` переключает на сопоставление, зависящее от локали, а `(?a:...)` переключает на сопоставление только ASCII (по умолчанию). Это переопределение действует только внутри узкой встроенной группы, а исходный режим сопоставления восстанавливается за пределами группы.178179Добавлено в версии 3.6.180181Изменено в версии 3.7: Буквы `'a'`, `'L'` и `'u'` также могут использоваться в группе.182183**`(?>...)`**184185Пытается сопоставить `...` так, как если бы это было отдельное регулярное выражение, и в случае успеха продолжает сопоставлять остальную часть шаблона после него. Если последующий шаблон не соответствует, стек можно развернуть только до точки *до* `(?>...)`, потому что после выхода выражение, известное как *атомарная группа*, отбрасывает все точки стека внутри себя. Таким образом, `(?>.*).` никогда ничего не найдет, потому что сначала `.*` сопоставит все возможные символы, затем, не найдя, чему соответствовать, последний `.` не сможет совпасть. Поскольку в атомарной группе не сохраняется ни одной точки стека, а перед ней нет точки стека, всё выражение в итоге не сможет найти совпадение.186187Добавлено в версии 3.12.188189**`(?P<name>...)`**190191Аналогично обычным скобкам, но подстрока, найденная группой, доступна через символическое имя группы *name*. Имена групп должны быть допустимыми идентификаторами Python, а в шаблонах [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes) они могут содержать только байты в диапазоне ASCII. Каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является нумерованной группой, как если бы группа не была именованной.192193Именованные группы можно использовать в трех контекстах. Если шаблон `(?P<quote>['"]).*?(?P=quote)` (т.е. соответствие строке, заключенной в одинарные или двойные кавычки):194195| Контекст ссылки на группу «quote» | Способы ссылки на нее |196| --- | --- |197| в том же самом шаблоне | `(?P=quote)` (как показано) `\1` |198| при обработке объекта совпадения *m* | `m.group('quote')` `m.end('quote')` (и т.д.) |199| в строке, передаваемой в аргумент *repl* функции `re.sub()` | `\g<quote>` `\g<1>` `\1` |200201Изменено в версии 3.12: В шаблонах [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes) имя группы *name* может содержать только байты в диапазоне ASCII (`b'\x00'`-`b'\x7f'`).202203**`(?P=name)`**204205Обратная ссылка на именованную группу; соответствует любому тексту, который был найден ранее группой с именем *name*.206207**`(?#...)`**208209Комментарий; содержимое скобок просто игнорируется.210211**`(?=...)`**212213Совпадает, если `...` совпадает далее, но не потребляет ни одного символа строки. Это называется *опережающей проверкой*. Например, `Isaac (?=Asimov)` совпадет с `'Isaac '`, только если за ним следует `'Asimov'`.214215**`(?!...)`**216217Совпадает, если `...` не совпадает далее. Это *отрицательная опережающая проверка*. Например, `Isaac (?!Asimov)` совпадет с `'Isaac '`, только если за ним *не* следует `'Asimov'`.218219**`(?<=...)`**220221Совпадает, если текущей позиции в строке предшествует совпадение с `...`, которое заканчивается в текущей позиции. Это называется *положительной ретроспективной проверкой*. `(?<=abc)def` найдет совпадение в `'abcdef'`, поскольку ретроспективная проверка отступит на 3 символа и проверит, совпадает ли вложенный шаблон. Вложенный шаблон может соответствовать только строкам фиксированной длины, то есть `abc` или `a|b` разрешены, а `a*` и `a{3,4}` – нет. Обратите внимание, что шаблоны, начинающиеся с положительной ретроспективной проверки, не будут совпадать в начале искомой строки; скорее всего, следует использовать функцию [`search()`](https://python-all.ru/3.16/library/re.html#re.search), а не [`match()`](https://python-all.ru/3.16/library/re.html#re.match):222223```python224>>> import re225>>> m = re.search('(?<=abc)def', 'abcdef')226>>> m.group(0)227'def'228```229230Этот пример ищет слово, следующее за дефисом:231232```python233>>> m = re.search(r'(?<=-)\w+', 'spam-egg')234>>> m.group(0)235'egg'236```237238Изменено в версии 3.5: Добавлена поддержка ссылок на группы фиксированной длины.239240**`(?<!...)`**241242Совпадает, если текущей позиции в строке не предшествует совпадение с `...`. Это называется *отрицательной ретроспективной проверкой*. Аналогично положительным ретроспективным проверкам, вложенный шаблон может соответствовать только строкам фиксированной длины. Шаблоны, начинающиеся с отрицательной ретроспективной проверки, могут совпадать в начале искомой строки.243244**`(?(id/name)yes-pattern|no-pattern)`**245246Пытается сопоставить с `yes-pattern`, если группа с заданным *идентификатором* или *именем* существует, и с `no-pattern`, если нет. `no-pattern` является необязательным и может быть опущен. Например, `(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)` – плохой шаблон для email, который совпадает с `'<user@host.com>'`, а также с `'user@host.com'`, но не совпадает `'<user@host.com'` или `'user@host.com>'` целиком ([`re.search()`](https://python-all.ru/3.16/library/re.html#re.search) находит только `'user@host.com'` в первом случае).247248Изменено в версии 3.12: Идентификатор группы *id* может содержать только цифры ASCII. В шаблонах [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes) имя группы *name* может содержать только байты в диапазоне ASCII (`b'\x00'`-`b'\x7f'`).249250Специальные последовательности состоят из `'\'` и символа из списка ниже. Если обычный символ не является цифрой ASCII или буквой ASCII, то полученное регулярное выражение будет соответствовать второму символу. Например, `\$` соответствует символу `'$'`.251252**`\number`**253254Совпадает с содержимым группы с тем же номером. Группы нумеруются начиная с 1. Например, `(.+) \1` совпадает с `'the the'` или `'55 55'`, но не с `'thethe'` (обратите внимание на пробел после группы). Эта специальная последовательность может использоваться только для сопоставления с одной из первых 99 групп. Если первая цифра *числа* равна 0, или *число* состоит из 3 восьмеричных цифр, оно не будет интерпретироваться как ссылка на группу, а как символ с восьмеричным значением *числа*. Внутри `'['` и `']'` символьного класса все числовые управляющие последовательности рассматриваются как символы.255256**`\A`**257258Совпадает только в начале строки.259260**`\b`**261262Совпадает с пустой строкой, но только в начале или конце слова. Слово определяется как последовательность символов слова. Обратите внимание, что формально `\b` определяется как граница между символом `\w` и символом `\W` (или наоборот), или между `\w` и началом или концом строки. Это означает, что `r'\bat\b'` совпадает с `'at'`, `'at.'`, `'(at)'`, и `'as at ay'`, но не с `'attempt'` или `'atlas'`.263264Символы слова по умолчанию в шаблонах Unicode (str) – это буквенно-цифровые символы Unicode и символ подчеркивания, но это можно изменить, используя флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII). Границы слов определяются текущей локалью, если используется флаг [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE).265266> **Примечание**267>268> Внутри диапазона символов `\b` представляет символ backspace, для совместимости со строковыми литералами Python.269270**`\B`**271272Совпадает с пустой строкой, но только когда она *не* находится в начале или конце слова. Это означает, что `r'at\B'` совпадает с `'athens'`, `'atom'`, `'attorney'`, но не с `'at'`, `'at.'` или `'at!'`. `\B` является противоположностью `\b`, поэтому символами слова в шаблонах Unicode (str) являются буквенно-цифровые символы Unicode или подчеркивание, хотя это можно изменить с помощью флага [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII). Границы слов определяются текущей локалью, если используется флаг [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE).273274Изменено в версии 3.14: `\B` теперь соответствует пустой входной строке.275276**`\d`**277278**Для шаблонов Unicode (str):**279280Соответствует любой десятичной цифре Unicode (то есть любому символу из категории Unicode [\[Nd\]](https://python-all.ru/3.16/library/re.html)). Включает `[0-9]`, а также множество других цифровых символов.281282Соответствует `[0-9]`, если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).283284**Для 8-битных (байтовых) шаблонов:**285286Соответствует любой десятичной цифре из набора символов ASCII; это эквивалентно `[0-9]`.287288**`\D`**289290Соответствует любому символу, не являющемуся десятичной цифрой. Это противоположность `\d`.291292Соответствует `[^0-9]`, если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).293294**`\s`**295296**Для шаблонов Unicode (str):**297298Соответствует пробельным символам Unicode (как определено в [`str.isspace()`](https://python-all.ru/3.16/library/stdtypes.html#str.isspace)). Включает `[ \t\n\r\f\v]`, а также множество других символов, например неразрывные пробелы, требуемые правилами типографики во многих языках.299300Соответствует `[ \t\n\r\f\v]`, если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).301302**Для 8-битных (байтовых) шаблонов:**303304Соответствует символам, считающимся пробельными в наборе символов ASCII; это эквивалентно `[ \t\n\r\f\v]`.305306**`\S`**307308Соответствует любому символу, не являющемуся пробельным. Это противоположность `\s`.309310Соответствует `[^ \t\n\r\f\v]`, если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).311312**`\w`**313314**Для шаблонов Unicode (str):**315316Соответствует символам слов Unicode; включает все буквенно-цифровые символы Unicode (как определено в [`str.isalnum()`](https://python-all.ru/3.16/library/stdtypes.html#str.isalnum)), а также символ подчеркивания (`_`).317318Соответствует `[a-zA-Z0-9_]`, если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).319320**Для 8-битных (байтовых) шаблонов:**321322Соответствует символам, считающимся буквенно-цифровыми в наборе символов ASCII; это эквивалентно `[a-zA-Z0-9_]`. Если используется флаг [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE), соответствует символам, считающимся буквенно-цифровыми в текущей локали, и символу подчеркивания.323324**`\W`**325326Соответствует любому символу, не являющемуся символом слова. Это противоположность `\w`. По умолчанию соответствует не-подчеркиванию (`_`) символам, для которых [`str.isalnum()`](https://python-all.ru/3.16/library/stdtypes.html#str.isalnum) возвращает `False`.327328Соответствует `[^a-zA-Z0-9_]`, если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).329330Если используется флаг [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE), соответствует символам, не являющимся ни буквенно-цифровыми в текущей локали, ни символом подчеркивания.331332**`\p{property=value}`, `\p{value}`**333334Соответствует любому символу с заданным свойством Unicode (см. [Unicode Technical Standard #18](https://python-all.ru/3.16/library/re.html), требование RL1.2 «Свойства»). Имена свойств и значений сопоставляются неточно: регистр, пробельные символы, `'-'` и `'_'` игнорируются. Поддерживаются следующие свойства:335336- Свойство `General_Category` (короткое имя `gc`), записываемое как `\p{Lu}`, `\p{gc=Lu}` или, для однобуквенной группы, `\p{L}`. Поддерживаемые значения – группы `L`, `N`, `Z` и `C`, а также значения `Lu`, `Lt`, `Lm`, `Nd`, `Nl`, `No`, `Zs`, `Zl`, `Zp`, `Cc`, `Cf`, `Cs`, `Co` и `Cn`.337- Бинарные свойства `XID_Start`, `XID_Continue`, `Alphabetic`, `Lowercase`, `Uppercase`, `Numeric`, `Printable`, `Cased` и `Case_Ignorable`. Бинарное свойство также может быть записано как `\p{name=yes}` или `\p{name=no}`.338- Классы совместимости POSIX `alpha`, `alnum`, `blank`, `cntrl`, `digit`, `graph`, `lower`, `print`, `space`, `upper`, `word` и `xdigit`.339- Свойства `ASCII`, `Any`, `Assigned`, `Noncharacter_Code_Point`, `Join_Control`, `Regional_Indicator`, `ASCII_Hex_Digit`, `Hex_Digit`, `Pattern_Syntax` и `Pattern_White_Space`.340341Если поддерживаемое свойство соответствует методу доступа [`unicodedata`](https://python-all.ru/3.16/library/unicodedata.html#module-unicodedata) или методу [`str`](https://python-all.ru/3.16/library/stdtypes.html#str), то набор символов, которым оно соответствует, в точности совпадает с тем, что они сообщают. Для согласованности с ними `space` следует [`str.isspace()`](https://python-all.ru/3.16/library/stdtypes.html#str.isspace) (как `\s`), а `xdigit` соответствует только шестнадцатеричным цифрам ASCII.342343Это распознаётся только в шаблонах Unicode (str). В байтовых шаблонах вызывает ошибку.344345Добавлено в версии 3.16.0a0 (не выпущено).346347**`\P{...}`**348349Соответствует любому символу, который *не* имеет заданное свойство Unicode. Это противоположность `\p`.350351Добавлено в версии 3.16.0a0 (не выпущено).352353**`\z`**354355Совпадение только в конце строки.356357Добавлено в версии 3.14.358359**`\Z`**360361То же, что и `\z`. Для совместимости со старыми версиями Python.362363Большинство [управляющих последовательностей](https://python-all.ru/3.16/reference/lexical_analysis.html#escape-sequences), поддерживаемых строковыми литералами Python, также принимаются парсером регулярных выражений:364365```python366\a \b \f \n367\N \r \t \u368\U \v \x \\369```370371(Обратите внимание, что `\b` используется для обозначения границ слов, а означает «забой» только внутри символьных классов.)372373Управляющие последовательности `'\u'`, `'\U'` и `'\N'` распознаются только в шаблонах Unicode (str). В байтовых шаблонах они вызывают ошибки. Неизвестные управляющие последовательности из букв ASCII зарезервированы для будущего использования и считаются ошибками.374375Восьмеричные управляющие последовательности поддерживаются в ограниченной форме. Если первая цифра – 0, или если есть три восьмеричных цифры, это считается восьмеричной управляющей последовательностью. В противном случае это ссылка на группу. Как и в строковых литералах, восьмеричные управляющие последовательности всегда имеют длину не более трёх цифр.376377Изменено в версии 3.3: Добавлены управляющие последовательности `'\u'` и `'\U'`.378379Изменено в версии 3.6: Неизвестные управляющие последовательности, состоящие из `'\'` и буквы ASCII, теперь вызывают ошибки.380381Изменено в версии 3.8: Добавлена управляющая последовательность `'\N{name}'`. Как и в строковых литералах, она раскрывается в именованный символ Unicode (например, `'\N{EM DASH}'`).382383## Содержимое модуля384385Модуль определяет несколько функций, констант и одно исключение. Некоторые из функций являются упрощёнными версиями полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используется скомпилированная форма.386387### Флаги388389Изменено в версии 3.6: Константы флагов теперь являются экземплярами [`RegexFlag`](https://python-all.ru/3.16/library/re.html#re.RegexFlag), который является подклассом [`enum.IntFlag`](https://python-all.ru/3.16/library/enum.html#enum.IntFlag).390391#### `class re.RegexFlag`392393Класс [`enum.IntFlag`](https://python-all.ru/3.16/library/enum.html#enum.IntFlag), содержащий перечисленные ниже опции регулярных выражений.394395Добавлено в версии 3.11: – добавлено в `__all__`396397#### `re.A`398399#### `re.ASCII`400401Заставляет `\w`, `\W`, `\b`, `\B`, `\d`, `\D`, `\s` и `\S` выполнять сопоставление только по ASCII вместо полного юникодного сопоставления. Это имеет смысл только для юникодных (str) шаблонов и игнорируется для байтовых шаблонов.402403Соответствует встроенному флагу `(?a)`.404405> **Примечание**406>407> Флаг [`U`](https://python-all.ru/3.16/library/re.html#re.U) всё ещё существует для обратной совместимости, но в Python 3 он избыточен, поскольку по умолчанию для шаблонов `str` используется юникодное сопоставление, а юникодное сопоставление не разрешено для байтовых шаблонов. [`UNICODE`](https://python-all.ru/3.16/library/re.html#re.UNICODE) и встроенный флаг `(?u)` также избыточны.408409#### `re.DEBUG`410411Отображает отладочную информацию о скомпилированном выражении.412413Нет соответствующего встроенного флага.414415#### `re.I`416417#### `re.IGNORECASE`418419Выполняет сопоставление без учёта регистра; выражения вроде `[A-Z]` также будут совпадать со строчными буквами. Полное юникодное сопоставление (например, `Ü` соответствует `ü`) также работает, если только флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII) не используется для отключения сопоставления не-ASCII. Текущая локаль не влияет на действие этого флага, если также не используется флаг [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE).420421Соответствует встроенному флагу `(?i)`.422423Обратите внимание, что при использовании юникодных шаблонов `[a-z]` или `[A-Z]` в сочетании с флагом [`IGNORECASE`](https://python-all.ru/3.16/library/re.html#re.IGNORECASE) они будут соответствовать 52 буквам ASCII и 4 дополнительным не-ASCII буквам: «İ» (U+0130, латинская заглавная буква I с точкой сверху), «ı» (U+0131, латинская строчная буква i без точки), «ſ» (U+017F, латинская строчная буква длинная s) и «K» (U+212A, знак Кельвина). Если используется флаг [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII), сопоставляются только буквы от «a» до «z» и от «A» до «Z».424425#### `re.L`426427#### `re.LOCALE`428429Делает `\w`, `\W`, `\b`, `\B` и сопоставление без учёта регистра зависимыми от текущей локали. Этот флаг можно использовать только с байтовыми шаблонами.430431Соответствует встроенному флагу `(?L)`.432433> **Предупреждение**434>435> Этот флаг не рекомендуется; вместо него используйте юникодное сопоставление. Механизм локали очень ненадёжен, так как он обрабатывает только одну «культуру» за раз и работает только с 8-битными локалями. Юникодное сопоставление включено по умолчанию для юникодных (str) шаблонов и способно обрабатывать разные локали и языки.436437Изменено в версии 3.6: [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE) можно использовать только с байтовыми шаблонами и несовместимо с [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII).438439Изменено в версии 3.7: Скомпилированные объекты регулярных выражений с флагом [`LOCALE`](https://python-all.ru/3.16/library/re.html#re.LOCALE) больше не зависят от локали во время компиляции. Только локаль во время сопоставления влияет на результат.440441#### `re.M`442443#### `re.MULTILINE`444445При указании этого флага символ шаблона `'^'` совпадает с началом строки и с началом каждой строки (сразу после каждого перевода строки); а символ шаблона `'$'` совпадает с концом строки и с концом каждой строки (непосредственно перед каждым переводом строки). По умолчанию `'^'` совпадает только с началом строки, а `'$'` – только с концом строки и непосредственно перед переводом строки (если он есть) в конце строки.446447Соответствует встроенному флагу `(?m)`.448449#### `re.NOFLAG`450451Указывает, что не применяется ни один флаг; значение равно `0`. Этот флаг можно использовать в качестве значения по умолчанию для именованного аргумента функции или в качестве базового значения, которое будет условно объединяться по OR с другими флагами. Пример использования в качестве значения по умолчанию:452453```python454def myfunc(pattern, text, flag=re.NOFLAG):455 return re.search(pattern, text, flag)456```457458Добавлено в версии 3.12.459460#### `re.S`461462#### `re.DOTALL`463464Заставляет специальный символ `'.'` совпадать с любым символом, включая перевод строки; без этого флага `'.'` будет совпадать с любым символом, *кроме* перевода строки.465466Соответствует встроенному флагу `(?s)`.467468#### `re.U`469470#### `re.UNICODE`471472В Python 3 символы Unicode сопоставляются по умолчанию для шаблонов `str`. Поэтому этот флаг избыточен **и не имеет эффекта**, он сохранён только для обратной совместимости.473474См. [`ASCII`](https://python-all.ru/3.16/library/re.html#re.ASCII), чтобы вместо этого ограничить сопоставление символами ASCII.475476#### `re.X`477478#### `re.VERBOSE`479480Этот флаг позволяет писать регулярные выражения, которые выглядят аккуратнее и более читаемы, позволяя визуально разделять логические секции шаблона и добавлять комментарии. Пробельные символы внутри шаблона игнорируются, за исключением случаев, когда они находятся внутри символьного класса, или перед ними стоит неэкранированный обратный слеш, или внутри токенов, таких как `*?`, `(?:` или `(?P<...>`. Например, `(? :` и `* ?` не допускаются. Когда строка содержит `#`, который не находится в символьном классе и перед ним нет неэкранированного обратного слеша, все символы от самого левого такого `#` до конца строки игнорируются.481482Это означает, что следующие два объекта регулярных выражений, которые сопоставляют десятичное число, функционально эквивалентны:483484```python485a = re.compile(r"""\d + # the integral part486 \. # the decimal point487 \d * # some fractional digits""", re.X)488b = re.compile(r"\d+\.\d*")489```490491Соответствует встроенному флагу `(?x)`.492493### Функции494495#### `re.compile(pattern, flags=0)`496497Компилирует шаблон регулярного выражения в [объект регулярного выражения](https://python-all.ru/3.16/library/re.html#re-objects), который можно использовать для сопоставления с помощью его методов [`prefixmatch()`](https://python-all.ru/3.16/library/re.html#re.Pattern.prefixmatch), [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search) и других, описанных ниже.498499Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).500501Последовательность502503```python504prog = re.compile(pattern)505result = prog.search(string)506```507508эквивалентна509510```python511result = re.search(pattern, string)512```513514но использование [`re.compile()`](https://python-all.ru/3.16/library/re.html#re.compile) и сохранение полученного объекта регулярного выражения для повторного использования более эффективно, когда выражение будет использоваться несколько раз в одной программе.515516> **Примечание**517>518> Скомпилированные версии последних шаблонов, переданных в [`re.compile()`](https://python-all.ru/3.16/library/re.html#re.compile) и функции сопоставления уровня модуля, кешируются, поэтому программам, использующим лишь несколько регулярных выражений за раз, не нужно беспокоиться о компиляции регулярных выражений.519520#### `re.search(pattern, string, flags=0)`521522Просматривает *string* в поисках первого места, где регулярное выражение *pattern* даёт совпадение, и возвращает соответствующий [`Match`](https://python-all.ru/3.16/library/re.html#re.Match). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в какой-то точке строки.523524Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).525526#### `re.prefixmatch(pattern, string, flags=0)`527528Если ноль или более символов в начале *string* соответствуют регулярному выражению *pattern*, возвращает соответствующий [`Match`](https://python-all.ru/3.16/library/re.html#re.Match). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.529530> **Примечание**531>532> Даже в режиме [`MULTILINE`](https://python-all.ru/3.16/library/re.html#re.MULTILINE) это будет сопоставляться только с началом строки, а не с началом каждой строки.533534Если нужно найти совпадение в любом месте *string*, используйте вместо этого [`search()`](https://python-all.ru/3.16/library/re.html#re.search) (см. также [search() vs. prefixmatch()](https://python-all.ru/3.16/library/re.html#search-vs-match)).535536Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).537538Теперь у этой функции два имени, и долгое время она была известна как [`match()`](https://python-all.ru/3.16/library/re.html#re.match). Используйте это имя, если нужно сохранить совместимость со старыми версиями Python.539540Добавлено в версии 3.15.541542#### `re.match(pattern, string, flags=0)`543544[Мягкое устаревание](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) начиная с версии 3.15: [`match()`](https://python-all.ru/3.16/library/re.html#re.match) было мягко устаревшим в пользу alternate [`prefixmatch()`](https://python-all.ru/3.16/library/re.html#re.prefixmatch) имени этого API, которое более явно описывает его. Используйте это имя, чтобы лучше выражать намерение. В других языках и реализациях регулярных выражений термин *match* используется для обозначения поведения, которое Python всегда называл [`search()`](https://python-all.ru/3.16/library/re.html#re.search). См. [prefixmatch() vs. match()](https://python-all.ru/3.16/library/re.html#prefixmatch-vs-match).545546#### `re.fullmatch(pattern, string, flags=0)`547548Если вся *string* соответствует регулярному выражению *pattern*, возвращает соответствующий [`Match`](https://python-all.ru/3.16/library/re.html#re.Match). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.549550Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).551552Добавлено в версии 3.4.553554#### `re.split(pattern, string, maxsplit=0, flags=0)`555556Разделяет *string* по вхождениям *pattern*. Если в *pattern* используются захватывающие круглые скобки, то текст всех групп в шаблоне также возвращается как часть результирующего списка. Если *maxsplit* не равно нулю, то происходит не более *maxsplit* разбиений, а остаток строки возвращается как последний элемент списка.557558```python559>>> re.split(r'\W+', 'Words, words, words.')560['Words', 'words', 'words', '']561>>> re.split(r'(\W+)', 'Words, words, words.')562['Words', ', ', 'words', ', ', 'words', '.', '']563>>> re.split(r'\W+', 'Words, words, words.', maxsplit=1)564['Words', 'words, words.']565>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)566['0', '3', '9']567```568569Если в разделителе есть захватывающие группы и он совпадает в начале строки, результат будет начинаться с пустой строки. То же самое относится и к концу строки:570571```python572>>> re.split(r'(\W+)', '...words, words...')573['', '...', 'words', ', ', 'words', '...', '']574```575576Таким образом, компоненты разделителя всегда находятся на одних и тех же относительных индексах в результирующем списке.577578Смежные пустые совпадения невозможны, но пустое совпадение может произойти сразу после непустого совпадения.579580```pycon581>>> re.split(r'\b', 'Words, words, words.')582['', 'Words', ', ', 'words', ', ', 'words', '.']583>>> re.split(r'\W*', '...words...')584['', '', 'w', 'o', 'r', 'd', 's', '', '']585>>> re.split(r'(\W*)', '...words...')586['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']587```588589Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).590591Изменено в версии 3.1: Добавлен необязательный аргумент flags.592593Изменено в версии 3.7: Добавлена возможность разделения по шаблону, который может соответствовать пустой строке.594595Устарело с версии 3.13: Передача *maxsplit* и *flags* в качестве позиционных аргументов устарела. В будущих версиях Python они станут [именованными параметрами](https://python-all.ru/3.16/glossary.html#keyword-only-parameter).596597#### `re.findall(pattern, string, flags=0)`598599Возвращает все непересекающиеся совпадения *pattern* в *string* в виде списка строк или кортежей. Строка *string* сканируется слева направо, совпадения возвращаются в порядке обнаружения. В результат включаются пустые совпадения.600601Результат зависит от количества захватывающих групп в шаблоне. Если групп нет, возвращается список строк, соответствующих всему шаблону. Если есть ровно одна группа, возвращается список строк, соответствующих этой группе. Если групп несколько, возвращается список кортежей строк, соответствующих группам. Незахватывающие группы не влияют на форму результата.602603```python604>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')605['foot', 'fell', 'fastest']606>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')607[('width', '20'), ('height', '10')]608```609610Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).611612Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.613614#### `re.finditer(pattern, string, flags=0)`615616Возвращает [итератор](https://python-all.ru/3.16/glossary.html#term-iterator), выдающий объекты [`Match`](https://python-all.ru/3.16/library/re.html#re.Match) для всех непересекающихся совпадений регулярного выражения *pattern* в строке *string*. Строка *string* сканируется слева направо, совпадения возвращаются в порядке обнаружения. Пустые совпадения включаются в результат.617618Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).619620Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.621622#### `re.sub(pattern, repl, string, count=0, flags=0)`623624Возвращает строку, полученную заменой крайних левых непересекающихся вхождений *pattern* в *string* на замену *repl*. Если шаблон не найден, возвращается *string* без изменений. *repl* может быть строкой или функцией; если это строка, все обратные слеши в ней обрабатываются. То есть `\n` преобразуется в символ новой строки, `\r` – в возврат каретки и так далее. Неизвестные управляющие последовательности из букв ASCII зарезервированы для будущего использования и считаются ошибками. Другие неизвестные последовательности, такие как `\&`, остаются без изменений. Обратные ссылки, например `\6`, заменяются подстрокой, соответствующей группе 6 в шаблоне. Например:625626```python627>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',628... r'static PyObject*\npy_\1(void)\n{',629... 'def myfunc():')630'static PyObject*\npy_myfunc(void)\n{'631```632633Если *repl* – функция, она вызывается для каждого непересекающегося вхождения *pattern*. Функция принимает единственный аргумент [`Match`](https://python-all.ru/3.16/library/re.html#re.Match) и возвращает строку замены. Например:634635```python636>>> def dashrepl(matchobj):637... if matchobj.group(0) == '-': return ' '638... else: return '-'639...640>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')641'pro--gram files'642>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)643'Baked Beans & Spam'644```645646Шаблон может быть строкой или [`Pattern`](https://python-all.ru/3.16/library/re.html#re.Pattern).647648Необязательный аргумент *count* – максимальное количество заменяемых вхождений шаблона; *count* должен быть неотрицательным целым числом. Если опущен или равен нулю, заменяются все вхождения.649650Смежные пустые совпадения невозможны, но пустое совпадение может произойти сразу после непустого. В результате `sub('x*', '-', 'abxd')` возвращает `'-a-b--d-'` вместо `'-a-b-d-'`.651652В строковых аргументах *repl*, помимо управляющих последовательностей и обратных ссылок, описанных выше, `\g<name>` использует подстроку, соответствующую группе с именем `name`, как определено синтаксисом `(?P<name>...)`. `\g<number>` использует соответствующий номер группы; таким образом, `\g<2>` эквивалентно `\2`, но не вызывает неоднозначности в такой замене, как `\g<2>0`. `\20` будет интерпретироваться как ссылка на группу 20, а не как ссылка на группу 2 с последующим литеральным символом `'0'`. Обратная ссылка `\g<0>` подставляет всю подстроку, соответствующую регулярному выражению.653654Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).655656Изменено в версии 3.1: Добавлен необязательный аргумент flags.657658Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.659660Изменено в версии 3.6: Неизвестные управляющие последовательности в *pattern*, состоящие из `'\'` и буквы ASCII, теперь считаются ошибками.661662Изменено в версии 3.7: Неизвестные управляющие последовательности в *repl*, состоящие из `'\'` и буквы ASCII, теперь считаются ошибками. Пустое совпадение может произойти сразу после непустого совпадения.663664Изменено в версии 3.12: Группа *id* может содержать только цифры ASCII. В строках замены [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes) группа *name* может содержать только байты в диапазоне ASCII (`b'\x00'`-`b'\x7f'`).665666Устарело с версии 3.13: Передача *count* и *flags* в качестве позиционных аргументов устарела. В будущих версиях Python они станут [именованными параметрами](https://python-all.ru/3.16/glossary.html#keyword-only-parameter).667668#### `re.subn(pattern, repl, string, count=0, flags=0)`669670Выполняет ту же операцию, что и [`sub()`](https://python-all.ru/3.16/library/re.html#re.sub), но возвращает кортеж `(new_string, number_of_subs_made)`.671672Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые переменные [flags](https://python-all.ru/3.16/library/re.html#flags), объединённые с помощью побитового ИЛИ (оператор `|`).673674#### `re.escape(pattern)`675676Экранирует специальные символы в *pattern*. Это полезно, если нужно сопоставить произвольную литеральную строку, которая может содержать метасимволы регулярных выражений. Например:677678```python679>>> print(re.escape('https://www.python.org'))680https://www\.python\.org681682>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"683>>> print('[%s]+' % re.escape(legal_chars))684[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+685686>>> operators = ['+', '-', '*', '/', '**']687>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))688/|\-|\+|\*\*|\*689```690691Эта функция не должна использоваться для строки замены в [`sub()`](https://python-all.ru/3.16/library/re.html#re.sub) и [`subn()`](https://python-all.ru/3.16/library/re.html#re.subn), экранировать следует только обратную косую черту. Например:692693```python694>>> digits_re = r'\d+'695>>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'696>>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))697/usr/sbin/sendmail - \d+ errors, \d+ warnings698```699700Изменено в версии 3.3: Символ `'_'` больше не экранируется.701702Изменено в версии 3.7: Теперь экранируются только символы, которые могут иметь специальное значение в регулярном выражении. В результате `'!'`, `'"'`, `'%'`, `"'"`, `','`, `'/'`, `':'`, `';'`, `'<'`, `'='`, `'>'`, `'@'` и `` "`" `` больше не экранируются.703704#### `re.purge()`705706Очищает кэш регулярных выражений.707708### Исключения709710#### `exception re.PatternError(msg, pattern=None, pos=None)`711712Исключение возникает, когда строка, переданная одной из функций здесь, не является допустимым регулярным выражением (например, может содержать несогласованные скобки), или когда во время компиляции или сопоставления происходит другая ошибка. Отсутствие совпадения шаблона в строке никогда не считается ошибкой. Экземпляр `PatternError` имеет следующие дополнительные атрибуты:713714#### `msg`715716Неформатированное сообщение об ошибке.717718#### `pattern`719720Шаблон регулярного выражения.721722#### `pos`723724Индекс в *pattern*, где произошла ошибка компиляции (может быть `None`).725726#### `lineno`727728Строка, соответствующая *pos* (может быть `None`).729730#### `colno`731732Столбец, соответствующий *pos* (может быть `None`).733734Изменено в версии 3.5: Добавлены дополнительные атрибуты.735736Изменено в версии 3.13: `PatternError` изначально назывался `error`; последний сохранён как псевдоним для обратной совместимости.737738## Объекты регулярных выражений739740#### `class re.Pattern`741742Скомпилированный объект регулярного выражения, возвращаемый [`re.compile()`](https://python-all.ru/3.16/library/re.html#re.compile).743744Шаблоны являются [обобщёнными](https://python-all.ru/3.16/library/typing.html#generics) относительно типа строки, с которой работают ([`str`](https://python-all.ru/3.16/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes)).745746Изменено в версии 3.9: `re.Pattern` поддерживает `[]` для указания шаблона Unicode (str) или bytes. См. [Общий тип псевдонима](https://python-all.ru/3.16/library/stdtypes.html#types-genericalias).747748#### `Pattern.search(string[, pos[, endpos]])`749750Просматривает *string* в поисках первой позиции, где данное регулярное выражение даёт совпадение, и возвращает соответствующий [`Match`](https://python-all.ru/3.16/library/re.html#re.Match). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в какой-либо точке строки.751752Необязательный второй параметр *pos* задаёт индекс в строке, с которого начинается поиск; по умолчанию `0`. Это не полностью эквивалентно срезу строки; символ шаблона `'^'` сопоставляется с реальным началом строки и с позициями сразу после символа новой строки, но не обязательно с индексом, с которого должен начинаться поиск.753754Необязательный параметр *endpos* ограничивает, как далеко будет просматриваться строка; считается, что строка имеет длину *endpos* символов, поэтому для совпадения будут просмотрены только символы от *pos* до `endpos - 1`. Если *endpos* меньше *pos*, совпадение не будет найдено; в противном случае, если *rx* – скомпилированный объект регулярного выражения, `rx.search(string, 0, 50)` эквивалентно `rx.search(string[:50], 0)`.755756```python757>>> pattern = re.compile("d")758>>> pattern.search("dog") # Совпадение на индексе 0759<re.Match object; span=(0, 1), match='d'>760>>> pattern.search("dog", 1) # Совпадения нет; поиск не включает "d"761```762763#### `Pattern.prefixmatch(string[, pos[, endpos]])`764765If zero or more characters at the *beginning* of *string* match this regular expression, return a corresponding [`Match`](https://python-all.ru/3.16/library/re.html#re.Match). Return `None` if the string does not match the pattern; note that this is different from a zero-length match.766767Обратите внимание, что даже в режиме [`MULTILINE`](https://python-all.ru/3.16/library/re.html#re.MULTILINE) это будет сопоставляться только с началом строки, а не с началом каждой строки.768769Необязательные параметры *pos* и *endpos* имеют то же значение, что и для метода [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search).770771```python772>>> pattern = re.compile("o")773>>> pattern.prefixmatch("dog") # Совпадения нет, так как "o" не в начале строки "dog".774>>> pattern.prefixmatch("dog", 1) # Совпадение есть, так как "o" – второй символ строки "dog".775<re.Match object; span=(1, 2), match='o'>776```777778Если нужно найти совпадение в любом месте *string*, используйте [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search) вместо этого (см. также [search() vs. prefixmatch()](https://python-all.ru/3.16/library/re.html#search-vs-match)).779780Теперь у этого метода два имени, и долгое время он был известен как [`match()`](https://python-all.ru/3.16/library/re.html#re.Pattern.match). Используйте это имя, если нужно сохранить совместимость со старыми версиями Python.781782Добавлено в версии 3.15.783784#### `Pattern.match(string[, pos[, endpos]])`785786[Мягко устарело](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.15: `match()` было мягко устарело в пользу альтернативного [`prefixmatch()`](https://python-all.ru/3.16/library/re.html#re.Pattern.prefixmatch) имени этого API, которое более явно описывает суть. Используйте его для более точного выражения намерения. В других языках и реализациях регулярных выражений принято использовать термин *match* для описания поведения, которое в Python всегда называлось [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search). См. [prefixmatch() vs. match()](https://python-all.ru/3.16/library/re.html#prefixmatch-vs-match).787788#### `Pattern.fullmatch(string[, pos[, endpos]])`789790Если вся *string* соответствует данному регулярному выражению, возвращает соответствующий [`Match`](https://python-all.ru/3.16/library/re.html#re.Match). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.791792Необязательные параметры *pos* и *endpos* имеют то же значение, что и для метода [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search).793794```python795>>> pattern = re.compile("o[gh]")796>>> pattern.fullmatch("dog") # Совпадения нет, так как "o" не в начале строки "dog".797>>> pattern.fullmatch("ogre") # Совпадения нет, так как не вся строка совпала.798>>> pattern.fullmatch("doggie", 1, 3) # Совпадения в заданных пределах.799<re.Match object; span=(1, 3), match='og'>800```801802Добавлено в версии 3.4.803804#### `Pattern.split(string, maxsplit=0)`805806Идентична функции [`split()`](https://python-all.ru/3.16/library/re.html#re.split), но использует скомпилированный шаблон.807808#### `Pattern.findall(string[, pos[, endpos]])`809810Похожа на функцию [`findall()`](https://python-all.ru/3.16/library/re.html#re.findall), использует скомпилированный шаблон, но также принимает необязательные параметры *pos* и *endpos*, ограничивающие область поиска, как и для [`search()`](https://python-all.ru/3.16/library/re.html#re.search).811812#### `Pattern.finditer(string[, pos[, endpos]])`813814Похожа на функцию [`finditer()`](https://python-all.ru/3.16/library/re.html#re.finditer), использует скомпилированный шаблон, но также принимает необязательные параметры *pos* и *endpos*, ограничивающие область поиска, как и для [`search()`](https://python-all.ru/3.16/library/re.html#re.search).815816#### `Pattern.sub(repl, string, count=0)`817818Идентична функции [`sub()`](https://python-all.ru/3.16/library/re.html#re.sub), но использует скомпилированный шаблон.819820#### `Pattern.subn(repl, string, count=0)`821822Идентична функции [`subn()`](https://python-all.ru/3.16/library/re.html#re.subn), но использует скомпилированный шаблон.823824#### `Pattern.flags`825826Флаги сопоставления регулярного выражения. Это комбинация флагов, переданных в [`compile()`](https://python-all.ru/3.16/library/re.html#re.compile), любых встроенных флагов `(?...)` в шаблоне, а также неявных флагов, таких как [`UNICODE`](https://python-all.ru/3.16/library/re.html#re.UNICODE), если шаблон является строкой Unicode.827828#### `Pattern.groups`829830Количество захватываемых групп в шаблоне.831832#### `Pattern.groupindex`833834Словарь, сопоставляющий символические имена групп, определённые через `(?P<id>)`, с номерами групп. Словарь пуст, если в шаблоне не использовались символические группы.835836#### `Pattern.pattern`837838Строка шаблона, из которой был скомпилирован объект шаблона.839840Изменено в версии 3.7: Добавлена поддержка [`copy.copy()`](https://python-all.ru/3.16/library/copy.html#copy.copy) и [`copy.deepcopy()`](https://python-all.ru/3.16/library/copy.html#copy.deepcopy). Скомпилированные объекты регулярных выражений считаются атомарными.841842## Объекты Match843844Объекты Match всегда имеют булево значение `True`. Поскольку [`match()`](https://python-all.ru/3.16/library/re.html#re.Pattern.match) и [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search) возвращают `None` при отсутствии совпадения, можно проверить, было ли совпадение, с помощью простого выражения `if`:845846```python847if match := re.search(pattern, string):848 process(match)849```850851#### `class re.Match`852853Объект Match, возвращаемый при успешных `match` и `search`.854855Объекты Match являются [обобщёнными](https://python-all.ru/3.16/library/typing.html#generics) по типу сопоставленной строки ([`str`](https://python-all.ru/3.16/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes)).856857Изменено в версии 3.9: `re.Match` поддерживает `[]` для указания сопоставления Unicode (str) или bytes. См. [Generic Alias Type](https://python-all.ru/3.16/library/stdtypes.html#types-genericalias).858859#### `Match.expand(template)`860861Возвращает строку, полученную путём замены обратной косой черты в строке шаблона *template*, как это делает метод [`sub()`](https://python-all.ru/3.16/library/re.html#re.Pattern.sub). Управляющие последовательности, такие как `\n`, преобразуются в соответствующие символы, а числовые обратные ссылки (`\1`, `\2`) и именованные обратные ссылки (`\g<1>`, `\g<name>`) заменяются содержимым соответствующей группы. Обратная ссылка `\g<0>` будет заменена на всё сопоставление.862863Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.864865#### `Match.group([group1, ...])`866867Возвращает одну или несколько подгрупп сопоставления. Если передан один аргумент, результатом является одна строка; если аргументов несколько – кортеж с одним элементом для каждого аргумента. Без аргументов *group1* по умолчанию равен нулю (возвращается всё сопоставление). Если аргумент *groupN* равен нулю, соответствующее возвращаемое значение – вся сопоставленная строка; если это положительное целое число – строка, соответствующая той же нумерованной группе. Если номер группы отрицателен или превышает количество групп, определённых в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.16/library/exceptions.html#IndexError). Если группа содержится в части шаблона, которая не сопоставилась, соответствующий результат равен `None`. Если группа содержится в части шаблона, которая сопоставилась несколько раз, возвращается последнее совпадение.868869```python870>>> m = re.search(r"\A(\w+) (\w+)", "Norwegian Blue, pining for the fjords")871>>> m.group(0) # Всё совпадение872'Norwegian Blue'873>>> m.group(1) # Первая группа в скобках.874'Norwegian'875>>> m.group(2) # Вторая группа в скобках.876'Blue'877>>> m.group(1, 2) # Несколько аргументов дают кортеж.878('Norwegian', 'Blue')879```880881Если регулярное выражение использует синтаксис `(?P<name>...)`, аргументы *groupN* также могут быть строками, идентифицирующими группы по их имени. Если строка не используется как имя группы в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.16/library/exceptions.html#IndexError).882883Довольно сложный пример:884885```python886>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit")887>>> m.group('adjective')888'killer'889>>> m.group('animal')890'rabbit'891```892893Именованные группы также можно указывать по их индексу:894895```python896>>> m.group(1)897'killer'898>>> m.group(2)899'rabbit'900```901902Если группа совпадает несколько раз, доступно только последнее совпадение:903904```python905>>> m = re.search(r"(..)+", "a1b2c3") # Совпадает 3 раза.906>>> m.group(1) # Возвращает только последнее совпадение.907'c3'908```909910#### `Match.__getitem__(g)`911912Это идентично `m.group(g)`. Это упрощает доступ к отдельной группе из совпадения:913914```python915>>> m = re.search(r"(\w+) (\w+)", "Norwegian Blue, pining for the fjords")916>>> m[0] # Всё совпадение917'Norwegian Blue'918>>> m[1] # Первая группа в скобках.919'Norwegian'920>>> m[2] # Вторая группа в скобках.921'Blue'922```923924Именованные группы также поддерживаются:925926```python927>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit")928>>> m['adjective']929'killer'930>>> m['animal']931'rabbit'932```933934Добавлено в версии 3.6.935936#### `Match.groups(default=None)`937938Возвращает кортеж, содержащий все подгруппы совпадения, от 1 до количества групп в шаблоне. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`.939940Например:941942```python943>>> m = re.search(r"(\d+)\.(\d+)", "24.1632")944>>> m.groups()945('24', '1632')946```947948Если сделать десятичную часть и всё после неё необязательными, не все группы могут участвовать в совпадении. Эти группы по умолчанию будут `None`, если не задан аргумент *default*:949950```python951>>> m = re.search(r"(\d+)\.?(\d+)?", "24")952>>> m.groups() # Вторая группа по умолчанию – None.953('24', None)954>>> m.groups('0') # Теперь вторая группа по умолчанию – '0'.955('24', '0')956```957958#### `Match.groupdict(default=None)`959960Возвращает словарь, содержащий все *именованные* подгруппы совпадения, где ключами являются имена подгрупп. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`. Например:961962```python963>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit")964>>> m.groupdict()965{'adjective': 'killer', 'animal': 'rabbit'}966```967968#### `Match.start([group])`969970#### `Match.end([group])`971972Возвращает индексы начала и конца подстроки, совпавшей с *group*; *group* по умолчанию равен нулю (означает всю совпавшую подстроку). Возвращает `-1`, если *group* существует, но не участвовала в совпадении. Для объекта совпадения *m* и группы *g*, которая участвовала в совпадении, подстрока, совпавшая с группой *g* (эквивалентно `m.group(g)`) – это973974```python975m.string[m.start(g):m.end(g)]976```977978Обратите внимание, что `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`](https://python-all.ru/3.16/library/exceptions.html#IndexError).979980Пример, который удалит *remove\_this* из адресов электронной почты:981982```python983>>> email = "tony@tiremove_thisger.net"984>>> m = re.search("remove_this", email)985>>> email[:m.start()] + email[m.end():]986'tony@tiger.net'987```988989#### `Match.span([group])`990991Для совпадения *m* возвращает кортеж из двух элементов `(m.start(group), m.end(group))`. Обратите внимание, что если *group* не участвовала в совпадении, это `(-1, -1)`. *group* по умолчанию равен нулю (всё совпадение).992993#### `Match.pos`994995Значение *pos*, которое было передано методу [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search) или [`match()`](https://python-all.ru/3.16/library/re.html#re.Pattern.match) объекта [regex object](https://python-all.ru/3.16/library/re.html#re-objects). Это индекс в строке, с которого движок регулярных выражений начал поиск совпадения.996997#### `Match.endpos`998999Значение *endpos*, которое было передано методу [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search) или [`match()`](https://python-all.ru/3.16/library/re.html#re.Pattern.match) объекта [regex object](https://python-all.ru/3.16/library/re.html#re-objects). Это индекс в строке, за который движок регулярных выражений не выйдет.10001001#### `Match.lastindex`10021003Целочисленный индекс последней совпавшей захватывающей группы или `None`, если ни одна группа не совпала. Например, выражения `(a)b`, `((a)(b))` и `((ab))` будут иметь `lastindex == 1`, если применить к строке `'ab'`, в то время как выражение `(a)(b)` будет иметь `lastindex == 2`, если применить к той же строке.10041005#### `Match.lastgroup`10061007Имя последней совпавшей захватывающей группы или `None`, если группа не имела имени, или если ни одна группа не совпала.10081009#### `Match.re`10101011[Объект регулярного выражения](https://python-all.ru/3.16/library/re.html#re-objects), чей метод [`match()`](https://python-all.ru/3.16/library/re.html#re.Pattern.match) или [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search) создал этот экземпляр совпадения.10121013#### `Match.string`10141015Строка, переданная в [`match()`](https://python-all.ru/3.16/library/re.html#re.Pattern.match) или [`search()`](https://python-all.ru/3.16/library/re.html#re.Pattern.search).10161017Изменено в версии 3.7: Добавлена поддержка [`copy.copy()`](https://python-all.ru/3.16/library/copy.html#copy.copy) и [`copy.deepcopy()`](https://python-all.ru/3.16/library/copy.html#copy.deepcopy). Объекты Match считаются атомарными.10181019## Примеры регулярных выражений10201021### Проверка на пару10221023В этом примере используется следующая вспомогательная функция для более наглядного отображения объектов совпадения:10241025```python1026def displaymatch(match):1027 if match is None:1028 return None1029 return '<Match: %r, groups=%r>' % (match.group(), match.groups())1030```10311032Допустим, пишется программа для покера, где рука игрока представлена в виде строки из 5 символов, каждый символ обозначает карту: «a» – туз, «k» – король, «q» – дама, «j» – валет, «t» – десятка, а «2»–«9» – карты соответствующего достоинства.10331034Чтобы проверить, является ли заданная строка допустимой рукой, можно поступить следующим образом:10351036```python1037>>> valid_hand_re = re.compile(r"^[a2-9tjqk]{5}$")1038>>> displaymatch(valid_hand_re.search("akt5q")) # Допустимо.1039"<Match: 'akt5q', groups=()>"1040>>> displaymatch(valid_hand_re.search("akt5e")) # Недопустимо.1041>>> displaymatch(valid_hand_re.search("akt")) # Недопустимо.1042>>> displaymatch(valid_hand_re.search("727ak")) # Допустимо.1043"<Match: '727ak', groups=()>"1044```10451046Последняя рука, `"727ak"`, содержала пару, то есть две карты одного достоинства. Чтобы найти такое совпадение с помощью регулярного выражения, можно использовать обратные ссылки следующим образом:10471048```python1049>>> pair_re = re.compile(r".*(.).*\1")1050>>> displaymatch(pair_re.prefixmatch("717ak")) # Пара семёрок.1051"<Match: '717', groups=('7',)>"1052>>> displaymatch(pair_re.prefixmatch("718ak")) # Нет пар.1053>>> displaymatch(pair_re.prefixmatch("354aa")) # Пара тузов.1054"<Match: '354aa', groups=('a',)>"1055```10561057Чтобы узнать, из какой карты состоит пара, можно использовать метод [`group()`](https://python-all.ru/3.16/library/re.html#re.Match.group) объекта совпадения следующим образом:10581059```python1060>>> pair_re = re.compile(r".*(.).*\1")1061>>> pair_re.prefixmatch("717ak").group(1)1062'7'10631064# Error because prefixmatch() returns None, which doesn't have a group() method:1065>>> pair_re.prefixmatch("718ak").group(1)1066Traceback (most recent call last):1067 File "<pyshell#23>", line 1, in <module>1068 pair_re.prefixmatch("718ak").group(1)1069AttributeError: 'NoneType' object has no attribute 'group'10701071>>> pair_re.prefixmatch("354aa").group(1)1072'a'1073```10741075### Эмуляция scanf()10761077В Python на данный момент нет аналога `scanf()`. Регулярные выражения в целом мощнее, но и более многословны, чем строки формата `scanf()`. В таблице ниже приведены более или менее эквивалентные соответствия между токенами формата `scanf()` и регулярными выражениями.10781079| `scanf()` Токен | Регулярное выражение |1080| --- | --- |1081| `%c` | `.` |1082| `%5c` | `.{5}` |1083| `%d` | `[-+]?\d+` |1084| `%e`, `%E`, `%f`, `%g` | `[-+]?(\d+(\.\d*)?\|\.\d+)([eE][-+]?\d+)?` |1085| `%i` | `[-+]?(0[xX][\dA-Fa-f]+\|0[0-7]*\|\d+)` |1086| `%o` | `[-+]?[0-7]+` |1087| `%s` | `\S+` |1088| `%u` | `\d+` |1089| `%x`, `%X` | `[-+]?(0[xX])?[\dA-Fa-f]+` |10901091Чтобы извлечь имя файла и числа из строки вида:10921093```text1094/usr/sbin/sendmail - 0 errors, 4 warnings1095```10961097используется формат `scanf()` следующего вида:10981099```text1100%s - %d errors, %d warnings1101```11021103Эквивалентное регулярное выражение:11041105```text1106(\S+) - (\d+) errors, (\d+) warnings1107```11081109### search() и prefixmatch()11101111Python предлагает различные примитивные операции на основе регулярных выражений:11121113- [`re.prefixmatch()`](https://python-all.ru/3.16/library/re.html#re.prefixmatch) ищет совпадение только в начале строки1114- [`re.search()`](https://python-all.ru/3.16/library/re.html#re.search) ищет совпадение в любом месте строки (именно так по умолчанию делает Perl)1115- [`re.fullmatch()`](https://python-all.ru/3.16/library/re.html#re.fullmatch) проверяет, является ли вся строка совпадением11161117Например:11181119```python1120>>> re.prefixmatch("c", "abcdef") # Нет совпадения.1121>>> re.search("c", "abcdef") # Совпадает.1122<re.Match object; span=(2, 3), match='c'>1123>>> re.fullmatch("p.*n", "python") # Совпадает.1124<re.Match object; span=(0, 6), match='python'>1125>>> re.fullmatch("r.*n", "python") # Нет совпадения.1126```11271128Регулярные выражения, начинающиеся с `'^'`, можно использовать с [`search()`](https://python-all.ru/3.16/library/re.html#re.search), чтобы ограничить совпадение началом строки:11291130```python1131>>> re.prefixmatch("c", "abcdef") # Нет совпадения.1132>>> re.search("^c", "abcdef") # Нет совпадения.1133>>> re.search("^a", "abcdef") # Совпадает.1134<re.Match object; span=(0, 1), match='a'>1135```11361137Обратите внимание, однако, что в режиме [`MULTILINE`](https://python-all.ru/3.16/library/re.html#re.MULTILINE) [`prefixmatch()`](https://python-all.ru/3.16/library/re.html#re.prefixmatch) соответствует только началу строки, тогда как использование [`search()`](https://python-all.ru/3.16/library/re.html#re.search) с регулярным выражением, начинающимся с `'^'`, будет соответствовать началу каждой строки.11381139```python1140>>> re.prefixmatch("X", "A\nB\nX", re.MULTILINE) # Нет совпадения.1141>>> re.search("^X", "A\nB\nX", re.MULTILINE) # Совпадает.1142<re.Match object; span=(4, 5), match='X'>1143```11441145### prefixmatch() и match()11461147Почему функция и метод [`match()`](https://python-all.ru/3.16/library/re.html#re.match) не рекомендуются в пользу более длинного написания [`prefixmatch()`](https://python-all.ru/3.16/library/re.html#re.prefixmatch)?11481149Многие другие языки получили библиотеки поддержки регулярных выражений с тех пор, как регулярные выражения были добавлены в Python. Однако в наиболее популярных из них они используют термин *match* для обозначения незакреплённого поведения, обеспечиваемого в Python функцией [`search()`](https://python-all.ru/3.16/library/re.html#re.search). Таким образом, использование простого термина *match* может быть непонятным для тех, кто привык к другим языкам при чтении или написании кода и не знаком с отклонением Python API от того, что в противном случае стало отраслевой нормой.11501151Цитируя Дзен Python (`python3 -m this`): *«Явное лучше неявного»*. Любой, кто читает имя `prefixmatch()`, скорее всего, поймёт предполагаемую семантику. При чтении `match()` остаётся доля сомнения относительно предполагаемого поведения у тех, кто ещё не знаком с этой старой ловушкой Python.11521153Мы **не** планируем удалять старое имя `match()`, поскольку оно используется в коде уже более 30 лет. Оно было [мягко устарело](https://python-all.ru/3.16/glossary.html#term-soft-deprecated): код, поддерживающий старые версии Python, должен продолжать использовать `match()`, в то время как новый код должен предпочитать `prefixmatch()`.11541155Добавлено в версии 3.15: `prefixmatch()`11561157[Мягко устарело](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.15: `match()`11581159### Создание телефонной книги11601161[`split()`](https://python-all.ru/3.16/library/re.html#re.split) разделяет строку на список, разделённый переданным шаблоном. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые можно легко читать и изменять с помощью Python, как показано в следующем примере, создающем телефонную книгу.11621163Сначала приведём входные данные. Обычно они могут поступать из файла, здесь используется синтаксис строки в тройных кавычках.11641165```pycon1166>>> text = """Ross McFluff: 834.345.1254 155 Elm Street1167...1168... Ronald Heathmore: 892.345.3428 436 Finley Avenue1169... Frank Burger: 925.541.7625 662 South Dogwood Way1170...1171...1172... Heather Albrecht: 548.326.4584 919 Park Place"""1173```11741175Записи разделяются одним или несколькими символами новой строки. Теперь преобразуем строку в список, где каждая непустая строка будет отдельной записью:11761177```pycon1178>>> entries = re.split("\n+", text)1179>>> entries1180['Ross McFluff: 834.345.1254 155 Elm Street',1181'Ronald Heathmore: 892.345.3428 436 Finley Avenue',1182'Frank Burger: 925.541.7625 662 South Dogwood Way',1183'Heather Albrecht: 548.326.4584 919 Park Place']1184```11851186Наконец, разделим каждую запись на список, содержащий имя, фамилию, номер телефона и адрес. Используем параметр `maxsplit` функции [`split()`](https://python-all.ru/3.16/library/re.html#re.split), потому что адрес содержит пробелы, которые являются нашим разделителем:11871188```pycon1189>>> [re.split(":? ", entry, maxsplit=3) for entry in entries]1190[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],1191['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],1192['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],1193['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]1194```11951196Шаблон `:?` соответствует двоеточию после фамилии, поэтому оно не попадает в результирующий список. Задав значение `maxsplit` равным `4`, можно было бы отделить номер дома от названия улицы:11971198```pycon1199>>> [re.split(":? ", entry, maxsplit=4) for entry in entries]1200[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],1201['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],1202['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],1203['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]1204```12051206### Преобразование текста12071208[`sub()`](https://python-all.ru/3.16/library/re.html#re.sub) заменяет каждое вхождение шаблона на строку или результат функции. Этот пример демонстрирует использование `sub()` с функцией для «мунгирования» текста, то есть случайного изменения порядка всех символов в каждом слове предложения, кроме первого и последнего:12091210```python1211>>> def repl(m):1212... inner_word = list(m.group(2))1213... random.shuffle(inner_word)1214... return m.group(1) + "".join(inner_word) + m.group(3)1215...1216>>> text = "Professor Abdolmalek, please report your absences promptly."1217>>> re.sub(r"(\w)(\w+)(\w)", repl, text)1218'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'1219>>> re.sub(r"(\w)(\w+)(\w)", repl, text)1220'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'1221```12221223### Поиск всех наречий12241225[`findall()`](https://python-all.ru/3.16/library/re.html#re.findall) находит *все* вхождения шаблона, а не только первое, как [`search()`](https://python-all.ru/3.16/library/re.html#re.search). Например, если требуется найти все наречия в тексте, можно использовать `findall()` следующим образом:12261227```python1228>>> text = "He was carefully disguised but captured quickly by police."1229>>> re.findall(r"\w+ly\b", text)1230['carefully', 'quickly']1231```12321233### Поиск всех наречий и их позиций12341235Если требуется получить больше информации о всех совпадениях шаблона, чем просто совпавший текст, [`finditer()`](https://python-all.ru/3.16/library/re.html#re.finditer) удобен, так как он возвращает объекты [`Match`](https://python-all.ru/3.16/library/re.html#re.Match) вместо строк. Продолжая предыдущий пример, если требуется найти все наречия *и их позиции* в тексте, можно воспользоваться `finditer()` следующим образом:12361237```python1238>>> text = "He was carefully disguised but captured quickly by police."1239>>> for m in re.finditer(r"\w+ly\b", text):1240... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))124107-16: carefully124240-47: quickly1243```12441245### Сырые строки12461247Нотация сырых строк (`r"text"`) сохраняет регулярные выражения в удобочитаемом виде. Без неё каждый обратный слеш (`'\'`) в регулярном выражении пришлось бы экранировать ещё одним таким же слешем. Например, следующие две строки кода функционально идентичны:12481249```python1250>>> re.search(r"\W(.)\1\W", " ff ")1251<re.Match object; span=(0, 4), match=' ff '>1252>>> re.search("\\W(.)\\1\\W", " ff ")1253<re.Match object; span=(0, 4), match=' ff '>1254```12551256Чтобы сопоставить буквальный обратный слеш, его нужно экранировать в регулярном выражении. В нотации сырых строк это означает `r"\\"`. Без нотации сырых строк нужно использовать `"\\\\"`, поэтому следующие строки кода функционально идентичны:12571258```python1259>>> re.search(r"\\", r"\\")1260<re.Match object; span=(0, 1), match='\\'>1261>>> re.search("\\\\", r"\\")1262<re.Match object; span=(0, 1), match='\\'>1263```12641265### Написание токенизатора12661267[Токенизатор или сканер](https://python-all.ru/3.16/library/re.html) анализирует строку, чтобы разделить символы на группы. Это полезный первый шаг при написании компилятора или интерпретатора.12681269Категории текста задаются с помощью регулярных выражений. Метод заключается в том, чтобы объединить их в одно главное регулярное выражение и перебирать последовательные совпадения:12701271```python1272from typing import NamedTuple1273import re12741275class Token(NamedTuple):1276 type: str1277 value: int | float | str1278 line: int1279 column: int12801281def tokenize(code):1282 keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}1283 token_specification = [1284 ('NUMBER', r'\d+(\.\d*)?'), # Целое или десятичное число.1285 ('ASSIGN', r':='), # Оператор присваивания.1286 ('END', r';'), # Терминатор инструкции.1287 ('ID', r'[A-Za-z]+'), # Идентификаторы.1288 ('OP', r'[+\-*/]'), # Арифметические операторы.1289 ('NEWLINE', r'\n'), # Концы строк.1290 ('SKIP', r'[ \t]+'), # Пропускать пробелы и табуляции.1291 ('MISMATCH', r'.'), # Любой другой символ.1292 ]1293 tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)1294 line_num = 11295 line_start = 01296 for mo in re.finditer(tok_regex, code):1297 kind = mo.lastgroup1298 value = mo.group()1299 column = mo.start() - line_start1300 if kind == 'NUMBER':1301 value = float(value) if '.' in value else int(value)1302 elif kind == 'ID' and value in keywords:1303 kind = value1304 elif kind == 'NEWLINE':1305 line_start = mo.end()1306 line_num += 11307 continue1308 elif kind == 'SKIP':1309 continue1310 elif kind == 'MISMATCH':1311 raise RuntimeError(f'{value!r} unexpected on line {line_num}')1312 yield Token(kind, value, line_num, column)13131314statements = '''1315 IF quantity THEN1316 total := total + price * quantity;1317 tax := price * 0.05;1318 ENDIF;1319'''13201321for token in tokenize(statements):1322 print(token)1323```13241325Токенизатор выдаёт следующий результат:13261327```python1328Token(type='IF', value='IF', line=2, column=4)1329Token(type='ID', value='quantity', line=2, column=7)1330Token(type='THEN', value='THEN', line=2, column=16)1331Token(type='ID', value='total', line=3, column=8)1332Token(type='ASSIGN', value=':=', line=3, column=14)1333Token(type='ID', value='total', line=3, column=17)1334Token(type='OP', value='+', line=3, column=23)1335Token(type='ID', value='price', line=3, column=25)1336Token(type='OP', value='*', line=3, column=31)1337Token(type='ID', value='quantity', line=3, column=33)1338Token(type='END', value=';', line=3, column=41)1339Token(type='ID', value='tax', line=4, column=8)1340Token(type='ASSIGN', value=':=', line=4, column=12)1341Token(type='ID', value='price', line=4, column=15)1342Token(type='OP', value='*', line=4, column=21)1343Token(type='NUMBER', value=0.05, line=4, column=23)1344Token(type='END', value=';', line=4, column=27)1345Token(type='ENDIF', value='ENDIF', line=5, column=4)1346Token(type='END', value=';', line=5, column=9)1347```13481349\[[Frie09](https://python-all.ru/3.16/library/re.html#id1)\]13501351Фридл, Джеффри. «Освоение регулярных выражений». 3-е изд., O’Reilly Media, 2009. Третье издание книги больше не рассматривает Python, но первое издание очень подробно освещает написание хороших шаблонов регулярных выражений.1352