re.md
1> **Источник:** https://python-all.ru/3.5/library/re.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 6.2. [`re`](https://python-all.ru/3.5/library/re.html#module-re) – Операции с регулярными выражениями89**Исходный код:** [Lib/re.py](https://python-all.ru/src/3.5/Lib/re.py)1011---1213Этот модуль предоставляет операции сопоставления с регулярными выражениями, аналогичные тем, что есть в Perl.1415И шаблоны, и искомые строки могут быть как строками Unicode, так и 8-битными строками. Однако смешивать строки Unicode и 8-битные строки нельзя: то есть нельзя сопоставить строку Unicode с байтовым шаблоном и наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон, и искомая строка.1617В регулярных выражениях обратная косая черта (`'\'`) используется для обозначения специальных форм или чтобы разрешить использование специальных символов без их специального значения. Это противоречит использованию того же символа в Python для той же цели в строковых литералах; например, чтобы сопоставить буквальную обратную косую черту, возможно, придётся написать `'\\\\'` в строке шаблона, потому что регулярное выражение должно быть `\\`, а каждую обратную косую черту нужно выразить как `\\` внутри обычного строкового литерала Python.1819Решение – использовать сырые строки Python для шаблонов регулярных выражений; обратные косые черты не обрабатываются особым образом в строковых литералах с префиксом `'r'`. Таким образом, `r"\n"` – это строка из двух символов, содержащая `'\'` и `'n'`, тогда как `"\n"` – это строка из одного символа, содержащая символ новой строки. Обычно шаблоны выражаются в коде Python с использованием этой нотации сырых строк.2021Важно отметить, что большинство операций с регулярными выражениями доступны как функции уровня модуля и методы [скомпилированных регулярных выражений](https://python-all.ru/3.5/library/re.html#re-objects). Функции – это ярлыки, которые не требуют предварительной компиляции объекта regex, но не имеют некоторых параметров тонкой настройки.2223> **См. также**24>25> Сторонний модуль [regex](https://python-all.ru/3.5/library/re.html), API которого совместим с модулем стандартной библиотеки [`re`](https://python-all.ru/3.5/library/re.html#module-re), но предлагает дополнительные функции и более полную поддержку Unicode.2627## 6.2.1. Синтаксис регулярных выражений2829Регулярное выражение (или RE) задаёт набор строк, которым оно соответствует; функции в этом модуле позволяют проверить, соответствует ли конкретная строка заданному регулярному выражению (или соответствует ли заданное регулярное выражение конкретной строке – что одно и то же).3031Регулярные выражения можно объединять для получения новых регулярных выражений; если *A* и *B* – регулярные выражения, то *AB* тоже регулярное выражение. В общем, если строка *p* соответствует *A*, а другая строка *q* соответствует *B*, то строка *pq* будет соответствовать AB. Это верно, если только *A* или *B* не содержат операций с низким приоритетом, граничных условий между *A* и *B* или нумерованных обращений к группам. Таким образом, сложные выражения легко строятся из более простых примитивных выражений, подобных описанным здесь. Подробнее о теории и реализации регулярных выражений см. книгу Фридла, указанную выше, или почти любой учебник по построению компиляторов.3233Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более доступного изложения обратитесь к [руководству по регулярным выражениям](https://python-all.ru/3.5/howto/regex.html#regex-howto).3435Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, например `'A'`, `'a'` или `'0'`, являются простейшими регулярными выражениями; они просто соответствуют сами себе. Можно объединять обычные символы, поэтому `last` соответствует строке `'last'`. (В оставшейся части этого раздела мы будем записывать RE в `this special style`, обычно без кавычек, а строки для сопоставления – в `'in single quotes'`.)3637Некоторые символы, например `'|'` или `'('`, являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на интерпретацию окружающих их регулярных выражений. Строки шаблонов регулярных выражений не могут содержать нулевые байты, но могут задавать нулевой байт с помощью нотации `\number`, например `'\x00'`.3839Квантификаторы повторения (`*`, `+`, `?`, `{m,n}` и т.д.) не могут быть непосредственно вложенными. Это позволяет избежать неоднозначности с суффиксом нежадного модификатора `?` и с другими модификаторами в других реализациях. Чтобы применить второе повторение к внутреннему повторению, можно использовать круглые скобки. Например, выражение `(?:a{6})*` соответствует любому кратному шести `'a'` символам.4041Специальные символы:4243**`'.'`**4445(Точка.) В режиме по умолчанию соответствует любому символу, кроме символа новой строки. Если указан флаг4647[`DOTALL`](https://python-all.ru/3.5/library/re.html#re.DOTALL)4849, то соответствует любому символу, включая символ новой строки.5051**`'^'`**5253(Циркумфлекс.) Соответствует началу строки, а в режиме5455[`MULTILINE`](https://python-all.ru/3.5/library/re.html#re.MULTILINE)5657также соответствует сразу после каждого символа новой строки.5859**`'$'`**6061Соответствует концу строки или непосредственно перед символом новой строки в конце строки, а в режиме6263[`MULTILINE`](https://python-all.ru/3.5/library/re.html#re.MULTILINE)6465также соответствует перед символом новой строки.6667`foo`6869соответствует и ‘foo’, и ‘foobar’, в то время как регулярное выражение7071`foo$`7273соответствует только ‘foo’. Интереснее то, что поиск7475`foo.$`7677в7879`'foo1\nfoo2\n'`8081обычно соответствует ‘foo2’, но в режиме8283[`MULTILINE`](https://python-all.ru/3.5/library/re.html#re.MULTILINE)8485– ‘foo1’; поиск одиночного8687`$`8889в9091`'foo\n'`9293найдет два (пустых) совпадения: одно сразу перед символом новой строки, и одно в конце строки.9495**`'*'`**9697Заставляет результирующее RE соответствовать 0 или более повторениям предыдущего RE, насколько это возможно.9899`ab*`100101будет соответствовать ‘a’, ‘ab’ или ‘a’, за которым следует любое количество символов ‘b’.102103**`'+'`**104105Заставляет результирующее RE соответствовать 1 или более повторениям предыдущего RE.106107`ab+`108109будет соответствовать ‘a’, за которым следует любое ненулевое количество символов ‘b’; оно не будет соответствовать просто ‘a’.110111**`'?'`**112113Заставляет результирующее RE соответствовать 0 или 1 повторению предыдущего RE.114115`ab?`116117будет соответствовать либо ‘a’, либо ‘ab’.118119**`*?`, `+?`, `??`**120121Квантификаторы122123`'*'`124125,126127`'+'`128129и130131`'?'`132133являются134135*жадными*136137; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если РВ138139`<.*>`140141сопоставить с142143`<a> b <c>`144145, оно будет соответствовать всей строке, а не только146147`<a>`148149. Добавление150151`?`152153после квантификатора заставляет его выполнять сопоставление в154155*нежадном*156157или158159*минимальном*160161режиме; будет сопоставлено как162163*можно меньше*164165символов. Использование РВ166167`<.*?>`168169будет соответствовать только170171`<a>`172173.174175**`{m}`**176177Указывает, что должно быть сопоставлено ровно178179*m*180181копий предыдущего RE; меньшее количество совпадений приводит к тому, что всё RE не соответствует. Например,182183`a{6}`184185будет соответствовать ровно шести символам186187`'a'`188189, но не пяти.190191**`{m,n}`**192193Заставляет результирующее RE соответствовать от194195*m*196197до198199*n*200201повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например,202203`a{3,5}`204205будет соответствовать от 3 до 5 символов206207`'a'`208209. Пропуск210211*m*212213задаёт нижнюю границу, равную нулю, а пропуск214215*n*216217задаёт бесконечную верхнюю границу. В качестве примера,218219`a{4,}b`220221будет соответствовать222223`aaaab`224225или тысяче символов226227`'a'`228229, за которыми следует230231`b`232233, но не234235`aaab`236237. Запятую нельзя опускать, иначе модификатор будет спутан с ранее описанной формой.238239**`{m,n}?`**240241Заставляет результирующее РВ соответствовать от242243*m*244245до246247*n*248249повторений предыдущего РВ, пытаясь сопоставить как250251*можно меньше*252253повторений. Это нежадная версия предыдущего квантификатора. Например, для 6-символьной строки254255`'aaaaaa'`256257,258259`a{3,5}`260261будет соответствовать 5262263`'a'`264265символам, в то время как266267`a{3,5}?`268269будет соответствовать только 3 символам.270271**`'\'`**272273Либо экранирует специальные символы (позволяя сопоставлять такие символы, как `'*'`, `'?'` и т.д.), либо обозначает специальную последовательность; специальные последовательности рассматриваются ниже.274275Если вы не используете сырую строку для выражения шаблона, помните, что Python также использует обратную косую черту как escape-последовательность в строковых литералах; если escape- последовательность не распознаётся парсером Python, обратная косая черта и следующий за ней символ включаются в результирующую строку. Однако если Python распознает результирующую последовательность, обратную косую черту следует удвоить. Это сложно и трудно для понимания, поэтому настоятельно рекомендуется использовать сырые строки для всех, кроме самых простых выражений.276277**`[]`**278279Используется для обозначения набора символов. В наборе:280281- Символы можно перечислять по отдельности, например, `[amk]` совпадет с `'a'`, `'m'` или `'k'`.282- Диапазоны символов можно задать, указав два символа и разделив их `'-'`, например `[a-z]` соответствует любой строчной букве ASCII, `[0-5][0-9]` – всем двузначным числам от `00` до `59`, а `[0-9A-Fa-f]` – любой шестнадцатеричной цифре. Если `-` экранирован (например, `[a\-z]`) или стоит первым или последним символом (например, `[a-]`), он соответствует литералу `'-'`.283- Специальные символы теряют своё специальное значение внутри наборов. Например, `[(+*)]` будет соответствовать любому из литеральных символов `'('`, `'+'`, `'*'` или `')'`.284- Классы символов, такие как `\w` или `\S` (определены ниже), также принимаются внутри набора, хотя символы, которым они соответствуют, зависят от того, активен ли режим [`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII) или [`LOCALE`](https://python-all.ru/3.5/library/re.html#re.LOCALE).285- Символы, не входящие в диапазон, можно сопоставить с помощью *дополнения* набора. Если первый символ набора – `'^'`, то будут сопоставлены все символы, которые *не* входят в набор. Например, `[^5]` совпадет с любым символом, кроме `'5'`, а `[^^]` – с любым символом, кроме `'^'`. `^` не имеет специального значения, если он не первый символ в наборе.286- Чтобы найти символ `']'` внутри набора, поставьте перед ним обратную косую черту или поместите его в начало набора. Например, `[()[\]{}]` и `[]()[{}]` оба соответствуют круглой скобке.287288**`'|'`**289290`A|B`291292, где A и B – произвольные РВ, создаёт регулярное выражение, которое соответствует либо A, либо B. Таким образом можно разделить любое количество РВ с помощью293294`'|'`295296. Это можно использовать и внутри групп (см. ниже). При сканировании целевой строки РВ, разделённые297298`'|'`299300, проверяются слева направо. Как только один шаблон полностью совпадает, эта ветвь принимается. Это означает, что как только301302`A`303304совпадает,305306`B`307308больше не проверяется, даже если он дал бы более длинное совпадение. Иными словами, оператор309310`'|'`311312никогда не является жадным. Чтобы сопоставить литерал313314`'|'`315316, используйте317318`\|`319320или заключите его в символьный класс, например321322`[|]`323324.325326**`(...)`**327328Соответствует любому регулярному выражению внутри скобок и обозначает начало и конец группы; содержимое группы можно извлечь после выполнения сопоставления, а также сопоставить позже в строке с помощью специальной последовательности329330`\number`331332, описанной ниже. Чтобы сопоставить литералы333334`'('`335336или337338`')'`339340, используйте341342`\(`343344или345346`\)`347348, или заключите их в символьный класс:349350`[(] [)]`351352.353354**`(?...)`**355356Это расширенная запись (иначе357358`'?'`359360после361362`'('`363364не имеет смысла). Первый символ после365366`'?'`367368определяет значение и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу;369370`(?P<name>...)`371372– единственное исключение из этого правила. Ниже перечислены поддерживаемые в настоящее время расширения.373374**`(?aiLmsux)`**375376(Одна или несколько букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`.) Группа соответствует пустой строке; буквы устанавливают соответствующие флаги: [`re.A`](https://python-all.ru/3.5/library/re.html#re.A) (только ASCII), [`re.I`](https://python-all.ru/3.5/library/re.html#re.I) (игнорирование регистра), [`re.L`](https://python-all.ru/3.5/library/re.html#re.L) (зависимость от локали), [`re.M`](https://python-all.ru/3.5/library/re.html#re.M) (многострочный режим), [`re.S`](https://python-all.ru/3.5/library/re.html#re.S) (точка соответствует всем символам) и [`re.X`](https://python-all.ru/3.5/library/re.html#re.X) (подробный режим) для всего регулярного выражения. (Флаги описаны в [Содержимое модуля](https://python-all.ru/3.5/library/re.html#contents-of-module-re).) Это полезно, если нужно включить флаги в само регулярное выражение, а не передавать аргумент *flag* функции [`re.compile()`](https://python-all.ru/3.5/library/re.html#re.compile).377378Обратите внимание, что флаг `(?x)` изменяет способ разбора выражения. Он должен быть указан первым в строке выражения или после одного или нескольких пробельных символов. Если перед флагом есть непробельные символы, результат не определён.379380**`(?:...)`**381382Незапоминающая версия обычных круглых скобок. Совпадает с любым регулярным выражением внутри скобок, но подстрока, совпавшая с группой,383384*не может*385386быть извлечена после выполнения сопоставления или использована для ссылки позже в шаблоне.387388**`(?P<name>...)`**389390Аналогично обычным круглым скобкам, но подстрока, совпавшая с группой, доступна по символическому имени группы *name*. Имена групп должны быть допустимыми идентификаторами Python, и каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является нумерованной группой, как если бы группа не была именованной.391392Именованные группы можно использовать в трех контекстах. Если шаблон `(?P<quote>['"]).*?(?P=quote)` (т.е. соответствие строке, заключенной в одинарные или двойные кавычки):393394| Контекст ссылки на группу «quote» | Способы ссылки на нее |395| --- | --- |396| в том же самом шаблоне | `(?P=quote)` (как показано) `\1` |397| при обработке объекта сопоставления `m` | `m.group('quote')` `m.end('quote')` (и т.д.) |398| в строке, переданной аргументу `repl` функции `re.sub()` | `\g<quote>` `\g<1>` `\1` |399400**`(?P=name)`**401402Обратная ссылка на именованную группу; соответствует любому тексту, который был найден ранее группой с именем403404*name*405406.407408**`(?#...)`**409410Комментарий; содержимое скобок просто игнорируется.411412**`(?=...)`**413414Соответствует, если415416`...`417418соответствует далее, но не поглощает ни одного символа строки. Это называется опережающей проверкой (lookahead assertion). Например,419420`Isaac (?=Asimov)`421422будет соответствовать423424`'Isaac '`425426, только если за ним следует427428`'Asimov'`429430.431432**`(?!...)`**433434Соответствует, если435436`...`437438не соответствует далее. Это отрицательная опережающая проверка. Например,439440`Isaac (?!Asimov)`441442будет соответствовать443444`'Isaac '`445446, только если за ним447448*не*449450следует451452`'Asimov'`453454.455456**`(?<=...)`**457458Совпадает, если текущей позиции в строке предшествует совпадение с `...`, которое заканчивается в текущей позиции. Это называется *положительной ретроспективной проверкой*. `(?<=abc)def` найдет совпадение в `abcdef`, поскольку ретроспективная проверка отступит на 3 символа и проверит, совпадает ли вложенный шаблон. Вложенный шаблон может соответствовать только строкам фиксированной длины, то есть `abc` или `a|b` разрешены, а `a*` и `a{3,4}` – нет. Обратите внимание, что шаблоны, начинающиеся с положительной ретроспективной проверки, не будут совпадать в начале искомой строки; скорее всего, следует использовать функцию [`search()`](https://python-all.ru/3.5/library/re.html#re.search), а не [`match()`](https://python-all.ru/3.5/library/re.html#re.match):459460```python461>>> import re462>>> m = re.search('(?<=abc)def', 'abcdef')463>>> m.group(0)464'def'465```466467Этот пример ищет слово, следующее за дефисом:468469```python470>>> m = re.search('(?<=-)\w+', 'spam-egg')471>>> m.group(0)472'egg'473```474475Изменено в версии 3.5: Добавлена поддержка ссылок на группы фиксированной длины.476477**`(?<!...)`**478479Совпадает, если текущей позиции в строке не предшествует совпадение с480481`...`482483. Это называется484485*отрицательной ретроспективной проверкой*486487. Аналогично положительным ретроспективным проверкам, вложенный шаблон может соответствовать только строкам фиксированной длины. Шаблоны, начинающиеся с отрицательной ретроспективной проверки, могут совпадать в начале искомой строки.488489**`(?(id/name)yes-pattern|no-pattern)`**490491Будет пытаться сопоставить с492493`yes-pattern`494495, если группа с заданным496497*id*498499или500501*именем*502503существует, и с504505`no-pattern`506507в противном случае.508509`no-pattern`510511необязателен и может быть опущен. Например,512513`(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)`514515– это неудачный шаблон для сопоставления email, который будет соответствовать516517`'<user@host.com>'`518519, а также520521`'user@host.com'`522523, но не524525`'<user@host.com'`526527и не528529`'user@host.com>'`530531.532533Специальные последовательности состоят из `'\'` и символа из списка ниже. Если обычный символ отсутствует в списке, то результирующее РВ будет соответствовать второму символу. Например, `\$` соответствует символу `'$'`.534535**`\number`**536537Совпадает с содержимым группы с тем же номером. Группы нумеруются начиная с 1. Например,538539`(.+) \1`540541совпадает с542543`'the the'`544545или546547`'55 55'`548549, но не с550551`'thethe'`552553(обратите внимание на пробел после группы). Эта специальная последовательность может использоваться только для сопоставления с одной из первых 99 групп. Если первая цифра554555*числа*556557равна 0, или558559*число*560561состоит из 3 восьмеричных цифр, оно не будет интерпретироваться как ссылка на группу, а как символ с восьмеричным значением562563*числа*564565. Внутри566567`'['`568569и570571`']'`572573символьного класса все числовые управляющие последовательности рассматриваются как символы.574575**`\A`**576577Совпадает только в начале строки.578579**`\b`**580581Соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность буквенно-цифровых символов Unicode или символов подчёркивания, поэтому конец слова обозначается пробелом или небуквенно-цифровым символом Unicode, не являющимся подчёркиванием. Обратите внимание, что формально `\b` определяется как граница между символом `\w` и символом `\W` (или наоборот), или между `\w` и началом/концом строки. Это означает, что `r'\bfoo\b'` соответствует `'foo'`, `'foo.'`, `'(foo)'`, `'bar foo baz'`, но не `'foobar'` или `'foo3'`.582583По умолчанию используются буквенно-цифровые символы Unicode, но это можно изменить с помощью флага [`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII). Внутри символьного диапазона `\b` представляет символ возврата (backspace) для совместимости со строковыми литералами Python.584585**`\B`**586587Соответствует пустой строке, но только когда она588589*не*590591находится в начале или конце слова. Это означает, что592593`r'py\B'`594595соответствует596597`'python'`598599,600601`'py3'`602603,604605`'py2'`606607, но не608609`'py'`610611,612613`'py.'`614615или616617`'py!'`618619.620621`\B`622623– это противоположность624625`\b`626627, поэтому символами слова являются буквенно-цифровые символы Unicode или символ подчёркивания, хотя это можно изменить с помощью флага628629[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)630631.632633**`\d`**634635**Для шаблонов Unicode (str):**636637Соответствует любой десятичной цифре Unicode (то есть любому символу из категории Unicode \[Nd\]). Сюда входит638639`[0-9]`640641, а также множество других цифровых символов. Если используется флаг642643[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)644645, сопоставление происходит только с646647`[0-9]`648649(но флаг влияет на всё регулярное выражение, поэтому в таких случаях может быть предпочтительнее явно указать650651`[0-9]`652653).654655**Для 8-битных (байтовых) шаблонов:**656657Соответствует любой десятичной цифре; это эквивалентно658659`[0-9]`660661.662663**`\D`**664665Соответствует любому символу, не являющемуся десятичной цифрой Unicode. Это противоположность666667`\d`668669. Если используется флаг670671[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)672673, это становится эквивалентом674675`[^0-9]`676677(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явный678679`[^0-9]`680681).682683**`\s`**684685**Для шаблонов Unicode (str):**686687Соответствует пробельным символам Unicode (включая688689`[ \t\n\r\f\v]`690691, а также множество других символов, например неразрывные пробелы, требуемые типографскими правилами во многих языках). Если используется флаг692693[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)694695, сопоставление происходит только с696697`[ \t\n\r\f\v]`698699(но флаг влияет на всё регулярное выражение, поэтому в таких случаях может быть предпочтительнее явно указать700701`[ \t\n\r\f\v]`702703).704705**Для 8-битных (байтовых) шаблонов:**706707Соответствует символам, считающимся пробельными в наборе символов ASCII; это эквивалентно708709`[ \t\n\r\f\v]`710711.712713**`\S`**714715Соответствует любому символу, не являющемуся пробельным символом Unicode. Это противоположность716717`\s`718719. Если используется флаг720721[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)722723, это становится эквивалентом724725`[^ \t\n\r\f\v]`726727(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явный728729`[^ \t\n\r\f\v]`730731).732733**`\w`**734735**Для шаблонов Unicode (str):**736737Соответствует символам слов Unicode; сюда входят большинство символов, которые могут быть частью слова в любом языке, а также цифры и символ подчёркивания. Если используется флаг738739[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)740741, сопоставление происходит только с742743`[a-zA-Z0-9_]`744745(но флаг влияет на всё регулярное выражение, поэтому в таких случаях может быть предпочтительнее явно указать746747`[a-zA-Z0-9_]`748749).750751**Для 8-битных (байтовых) шаблонов:**752753Соответствует символам, считающимся буквенно-цифровыми в наборе ASCII; это эквивалентно754755`[a-zA-Z0-9_]`756757.758759**`\W`**760761Соответствует любому символу, не являющемуся символом слова Unicode. Это противоположность762763`\w`764765. Если используется флаг766767[`ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII)768769, это становится эквивалентом770771`[^a-zA-Z0-9_]`772773(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явный774775`[^a-zA-Z0-9_]`776777).778779**`\Z`**780781Совпадение только в конце строки.782783Большинство стандартных управляющих последовательностей, поддерживаемых строковыми литералами Python, также принимаются синтаксическим анализатором регулярных выражений:784785```python786\a \b \f \n787\r \t \u \U788\v \x \\789```790791(Обратите внимание, что `\b` используется для обозначения границ слов, а означает «забой» только внутри символьных классов.)792793Управляющие последовательности `'\u'` и `'\U'` распознаются только в шаблонах Unicode. В байтовых шаблонах они не обрабатываются особым образом.794795Восьмеричные управляющие последовательности поддерживаются в ограниченной форме. Если первая цифра – 0, или если есть три восьмеричных цифры, это считается восьмеричной управляющей последовательностью. В противном случае это ссылка на группу. Как и в строковых литералах, восьмеричные управляющие последовательности всегда имеют длину не более трёх цифр.796797Изменено в версии 3.3: Добавлены управляющие последовательности `'\u'` и `'\U'`.798799Устарело с версии 3.5, будет удалено в версии 3.6: Неизвестные управляющие последовательности, состоящие из `'\'` и буквы ASCII, теперь вызывают предупреждение об устаревании и будут запрещены в Python 3.6.800801> **См. также**802>803> **Mastering Regular Expressions**804>805> Книга по регулярным выражениям Джеффри Фридла, издательство O’Reilly. Второе издание книги вообще не охватывает Python, но первое издание очень подробно описывает написание хороших шаблонов регулярных выражений.806807## 6.2.2. Содержимое модуля808809Модуль определяет несколько функций, констант и одно исключение. Некоторые из функций являются упрощёнными версиями полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используется скомпилированная форма.810811#### `re.compile(pattern, flags=0)`812813Компилирует шаблон регулярного выражения в объект регулярного выражения, который можно использовать для сопоставления с помощью его методов [`match()`](https://python-all.ru/3.5/library/re.html#re.regex.match) и [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search), описанных ниже.814815Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые из следующих переменных, комбинируя их с помощью побитового ИЛИ (оператор `|`).816817Последовательность818819```python820prog = re.compile(pattern)821result = prog.match(string)822```823824эквивалентна825826```python827result = re.match(pattern, string)828```829830но использование [`re.compile()`](https://python-all.ru/3.5/library/re.html#re.compile) и сохранение полученного объекта регулярного выражения для повторного использования более эффективно, когда выражение будет использоваться несколько раз в одной программе.831832> **Примечание**833>834> Скомпилированные версии последних шаблонов, переданных в [`re.compile()`](https://python-all.ru/3.5/library/re.html#re.compile) и функции сопоставления уровня модуля, кешируются, поэтому программам, использующим лишь несколько регулярных выражений за раз, не нужно беспокоиться о компиляции регулярных выражений.835836#### `re.A`837838#### `re.ASCII`839840Заставляет `\w`, `\W`, `\b`, `\B`, `\d`, `\D`, `\s` и `\S` выполнять сопоставление только по ASCII вместо полного сопоставления Unicode. Это имеет смысл только для шаблонов Unicode и игнорируется для байтовых шаблонов.841842Обратите внимание, что для обратной совместимости флаг `re.U` все еще существует (как и его синоним `re.UNICODE` и встроенный аналог `(?u)`), но они избыточны в Python 3, поскольку сопоставление по умолчанию для строк выполняется в Unicode (а сопоставление Unicode не допускается для байтов).843844#### `re.DEBUG`845846Отображает отладочную информацию о скомпилированном выражении.847848#### `re.I`849850#### `re.IGNORECASE`851852Выполняет сопоставление без учёта регистра; выражения вида `[A-Z]` будут соответствовать и строчным буквам. На это не влияет текущая локаль, и оно работает для символов Unicode как ожидается.853854#### `re.L`855856#### `re.LOCALE`857858Делает `\w`, `\W`, `\b`, `\B`, `\s` и `\S` зависимыми от текущей локали. Использовать этот флаг не рекомендуется, так как механизм локали очень ненадёжен и к тому же обрабатывает за раз только одну «культуру»; лучше использовать сопоставление Unicode, которое в Python 3 используется по умолчанию для строковых шаблонов (str). Этот флаг имеет смысл только для байтовых шаблонов.859860Устарело с версии 3.5, будет удалено в версии 3.6: Устарело использование [`re.LOCALE`](https://python-all.ru/3.5/library/re.html#re.LOCALE) со строковыми шаблонами или [`re.ASCII`](https://python-all.ru/3.5/library/re.html#re.ASCII).861862#### `re.M`863864#### `re.MULTILINE`865866При указании этого флага символ шаблона `'^'` совпадает с началом строки и с началом каждой строки (сразу после каждого перевода строки); а символ шаблона `'$'` совпадает с концом строки и с концом каждой строки (непосредственно перед каждым переводом строки). По умолчанию `'^'` совпадает только с началом строки, а `'$'` – только с концом строки и непосредственно перед переводом строки (если он есть) в конце строки.867868#### `re.S`869870#### `re.DOTALL`871872Заставляет специальный символ `'.'` совпадать с любым символом, включая перевод строки; без этого флага `'.'` будет совпадать с любым символом, *кроме* перевода строки.873874#### `re.X`875876#### `re.VERBOSE`877878Этот флаг позволяет писать регулярные выражения, которые выглядят аккуратнее и читаются проще: можно визуально разделять логические части шаблона и добавлять комментарии. Пробелы в шаблоне игнорируются, за исключением тех, что находятся внутри символьного класса или перед которыми стоит неэкранированный обратный слеш. Если строка содержит `#`, не находящийся в символьном классе и не предварённый неэкранированным обратным слешем, все символы от крайнего левого такого `#` до конца строки игнорируются.879880Это означает, что следующие два объекта регулярных выражений, которые сопоставляют десятичное число, функционально эквивалентны:881882```python883a = re.compile(r"""\d + # the integral part884 \. # the decimal point885 \d * # some fractional digits""", re.X)886b = re.compile(r"\d+\.\d*")887```888889#### `re.search(pattern, string, flags=0)`890891Просматривает строку *string* в поиске первой позиции, где регулярное выражение *pattern* даёт совпадение, и возвращает соответствующий [объект сопоставления](https://python-all.ru/3.5/library/re.html#match-objects). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска нулевого совпадения в какой-то точке строки.892893#### `re.match(pattern, string, flags=0)`894895Если ноль или более символов в начале строки *string* соответствуют регулярному выражению *pattern*, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.5/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.896897Обратите внимание, что даже в режиме [`MULTILINE`](https://python-all.ru/3.5/library/re.html#re.MULTILINE), [`re.match()`](https://python-all.ru/3.5/library/re.html#re.match) будет совпадать только в начале строки, а не в начале каждой строки.898899If you want to locate a match anywhere in *string*, use [`search()`](https://python-all.ru/3.5/library/re.html#re.search) instead (see also [search() vs. match()](https://python-all.ru/3.5/library/re.html#search-vs-match)).900901#### `re.fullmatch(pattern, string, flags=0)`902903Если вся строка *string* соответствует регулярному выражению *pattern*, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.5/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.904905Новое в версии 3.4.906907#### `re.split(pattern, string, maxsplit=0, flags=0)`908909Разделяет *string* по вхождениям *pattern*. Если в *pattern* используются захватывающие круглые скобки, то текст всех групп в шаблоне также возвращается как часть результирующего списка. Если *maxsplit* не равно нулю, то происходит не более *maxsplit* разбиений, а остаток строки возвращается как последний элемент списка.910911```python912>>> re.split('\W+', 'Words, words, words.')913['Words', 'words', 'words', '']914>>> re.split('(\W+)', 'Words, words, words.')915['Words', ', ', 'words', ', ', 'words', '.', '']916>>> re.split('\W+', 'Words, words, words.', 1)917['Words', 'words, words.']918>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)919['0', '3', '9']920```921922Если в разделителе есть захватывающие группы и он совпадает в начале строки, результат будет начинаться с пустой строки. То же самое относится и к концу строки:923924```python925>>> re.split('(\W+)', '...words, words...')926['', '...', 'words', ', ', 'words', '...', '']927```928929Таким образом, компоненты разделителя всегда находятся на одних и тех же относительных индексах в результирующем списке.930931> **Примечание**932>933> [`split()`](https://python-all.ru/3.5/library/re.html#re.split) в настоящее время не разбивает строку по совпадению с пустым шаблоном. Например:934>935> ```python936> >>> re.split('x*', 'axbc')937> ['a', 'bc']938> ```939>940> Несмотря на то, что `'x*'` также соответствует 0 ‘x’ перед ‘a’, между ‘b’ и ‘c’ и после ‘c’, в настоящее время эти совпадения игнорируются. Правильное поведение (т.е. разбиение также по пустым совпадениям с возвратом `['', 'a', 'b', 'c', '']`) будет реализовано в будущих версиях Python, но поскольку это обратно несовместимое изменение, пока будет вызываться [`FutureWarning`](https://python-all.ru/3.5/library/exceptions.html#FutureWarning).941>942> Шаблоны, которые могут соответствовать только пустым строкам, в настоящее время никогда не разбивают строку. Поскольку это не соответствует ожидаемому поведению, начиная с Python 3.5 будет вызываться [`ValueError`](https://python-all.ru/3.5/library/exceptions.html#ValueError):943>944> ```python945> >>> re.split("^$", "foo\n\nbar\n", flags=re.M)946> Traceback (most recent call last):947> File "<stdin>", line 1, in <module>948> ...949> ValueError: split() requires a non-empty pattern match.950> ```951952Изменено в версии 3.1: Добавлен необязательный аргумент flags.953954Изменено в версии 3.5: Разбиение по шаблону, который может соответствовать пустой строке, теперь вызывает предупреждение. Шаблоны, которые могут соответствовать только пустым строкам, теперь отклоняются.955956#### `re.findall(pattern, string, flags=0)`957958Возвращает все непересекающиеся совпадения *pattern* в *string*, в виде списка строк. Строка *string* сканируется слева направо, совпадения возвращаются в порядке обнаружения. Если в шаблоне присутствуют одна или несколько групп, возвращается список групп; если групп больше одной – список кортежей. Пустые совпадения включаются в результат, кроме случаев, когда они примыкают к началу другого совпадения.959960#### `re.finditer(pattern, string, flags=0)`961962Возвращает [итератор](https://python-all.ru/3.5/glossary.html#term-iterator), выдающий [объекты совпадений](https://python-all.ru/3.5/library/re.html#match-objects) по всем непересекающимся совпадениям регулярного выражения *pattern* в *string*. Строка *string* сканируется слева направо, совпадения возвращаются в порядке обнаружения. Пустые совпадения включаются в результат, кроме случаев, когда они примыкают к началу другого совпадения.963964#### `re.sub(pattern, repl, string, count=0, flags=0)`965966Возвращает строку, полученную заменой крайних левых непересекающихся вхождений *шаблона* в *строке* заменой *заменой*. Если шаблон не найден, возвращается *строка* без изменений. *замена* может быть строкой или функцией; если это строка, обрабатываются все escape-последовательности с обратной косой чертой. То есть `\n` преобразуется в символ новой строки, `\r` преобразуется в возврат каретки и так далее. Неизвестные escape-последовательности, такие как `\&`, остаются без изменений. Обратные ссылки, например `\6`, заменяются подстрокой, соответствующей группе 6 в шаблоне. Например:967968```python969>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',970... r'static PyObject*\npy_\1(void)\n{',971... 'def myfunc():')972'static PyObject*\npy_myfunc(void)\n{'973```974975Если *repl* – функция, она вызывается для каждого непересекающегося вхождения *pattern*. Функция принимает один аргумент – объект совпадения – и возвращает строку замены. Например:976977```python978>>> def dashrepl(matchobj):979... if matchobj.group(0) == '-': return ' '980... else: return '-'981>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')982'pro--gram files'983>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)984'Baked Beans & Spam'985```986987Шаблон может быть строкой или объектом RE.988989Необязательный аргумент *count* – максимальное количество вхождений шаблона, которые нужно заменить; *count* должен быть неотрицательным целым числом. Если он опущен или равен нулю, заменяются все вхождения. Пустые совпадения для шаблона заменяются только тогда, когда они не примыкают к предыдущему совпадению, поэтому `sub('x*', '-', 'abc')` возвращает `'-a-b-c-'`.990991В строковых аргументах *repl*, помимо управляющих последовательностей и обратных ссылок, описанных выше, `\g<name>` использует подстроку, соответствующую группе с именем `name`, как определено синтаксисом `(?P<name>...)`. `\g<number>` использует соответствующий номер группы; таким образом, `\g<2>` эквивалентно `\2`, но не вызывает неоднозначности в такой замене, как `\g<2>0`. `\20` будет интерпретироваться как ссылка на группу 20, а не как ссылка на группу 2 с последующим литеральным символом `'0'`. Обратная ссылка `\g<0>` подставляет всю подстроку, соответствующую регулярному выражению.992993Изменено в версии 3.1: Добавлен необязательный аргумент flags.994995Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.996997Устарело с версии 3.5, будет удалено в версии 3.6: Неизвестные управляющие последовательности, состоящие из `'\'` и буквы ASCII, теперь вызывают предупреждение об устаревании и будут запрещены в Python 3.6.998999#### `re.subn(pattern, repl, string, count=0, flags=0)`10001001Выполняет ту же операцию, что и [`sub()`](https://python-all.ru/3.5/library/re.html#re.sub), но возвращает кортеж `(new_string, number_of_subs_made)`.10021003Изменено в версии 3.1: Добавлен необязательный аргумент flags.10041005Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.10061007#### `re.escape(pattern)`10081009Экранирует все символы в *pattern*, кроме букв ASCII, цифр и `'_'`. Это полезно, если нужно сопоставить произвольную литеральную строку, которая может содержать метасимволы регулярных выражений. Например:10101011```python1012>>> print(re.escape('python.exe'))1013python\.exe10141015>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"1016>>> print('[%s]+' % re.escape(legal_chars))1017[abcdefghijklmnopqrstuvwxyz0123456789\!\#\$\%\&\'\*\+\-\.\^_\`\|\~\:]+10181019>>> operators = ['+', '-', '*', '/', '**']1020>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))1021\/|\-|\+|\*\*|\*1022```10231024Изменено в версии 3.3: Символ `'_'` больше не экранируется.10251026#### `re.purge()`10271028Очищает кэш регулярных выражений.10291030#### `exception re.error(msg, pattern=None, pos=None)`10311032Исключение возникает, когда переданная одной из функций строка не является корректным регулярным выражением (например, может содержать непарные скобки) или когда происходит другая ошибка во время компиляции или сопоставления. Если строка не содержит совпадений с шаблоном, это никогда не считается ошибкой. Экземпляр ошибки имеет следующие дополнительные атрибуты:10331034#### `msg`10351036Неформатированное сообщение об ошибке.10371038#### `pattern`10391040Шаблон регулярного выражения.10411042#### `pos`10431044Индекс в *pattern*, где произошла ошибка компиляции (может быть `None`).10451046#### `lineno`10471048Строка, соответствующая *pos* (может быть `None`).10491050#### `colno`10511052Столбец, соответствующий *pos* (может быть `None`).10531054Изменено в версии 3.5: Добавлены дополнительные атрибуты.10551056## 6.2.3. Объекты регулярных выражений10571058Скомпилированные объекты регулярных выражений поддерживают следующие методы и атрибуты:10591060#### `regex.search(string[, pos[, endpos]])`10611062Просматривает строку *string* в поиске первой позиции, где данное регулярное выражение даёт совпадение, и возвращает соответствующий [объект сопоставления](https://python-all.ru/3.5/library/re.html#match-objects). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска нулевого совпадения в какой-то точке строки.10631064Необязательный второй параметр *pos* задаёт индекс в строке, с которого начинается поиск; по умолчанию `0`. Это не полностью эквивалентно срезу строки; символ шаблона `'^'` сопоставляется с реальным началом строки и с позициями сразу после символа новой строки, но не обязательно с индексом, с которого должен начинаться поиск.10651066Необязательный параметр *endpos* ограничивает, как далеко будет просматриваться строка; считается, что строка имеет длину *endpos* символов, поэтому для совпадения будут просмотрены только символы от *pos* до `endpos - 1`. Если *endpos* меньше *pos*, совпадение не будет найдено; в противном случае, если *rx* – скомпилированный объект регулярного выражения, `rx.search(string, 0, 50)` эквивалентно `rx.search(string[:50], 0)`.10671068```python1069>>> pattern = re.compile("d")1070>>> pattern.search("dog") # Совпадение на индексе 01071<_sre.SRE_Match object; span=(0, 1), match='d'>1072>>> pattern.search("dog", 1) # Совпадения нет; поиск не включает "d"1073```10741075#### `regex.match(string[, pos[, endpos]])`10761077Если ноль или более символов в *начале* строки *string* соответствуют данному регулярному выражению, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.5/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.10781079Необязательные параметры *pos* и *endpos* имеют то же значение, что и для метода [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search).10801081```python1082>>> pattern = re.compile("o")1083>>> pattern.match("dog") # Совпадения нет, так как "o" не в начале строки "dog".1084>>> pattern.match("dog", 1) # Совпадение есть, так как "o" – второй символ строки "dog".1085<_sre.SRE_Match object; span=(1, 2), match='o'>1086```10871088Если требуется найти совпадение в любом месте *string*, используйте [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search) (см. также [search() vs. match()](https://python-all.ru/3.5/library/re.html#search-vs-match)).10891090#### `regex.fullmatch(string[, pos[, endpos]])`10911092Если вся строка *string* соответствует данному регулярному выражению, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.5/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.10931094Необязательные параметры *pos* и *endpos* имеют то же значение, что и для метода [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search).10951096```python1097>>> pattern = re.compile("o[gh]")1098>>> pattern.fullmatch("dog") # Совпадения нет, так как "o" не в начале строки "dog".1099>>> pattern.fullmatch("ogre") # Совпадения нет, так как не вся строка совпала.1100>>> pattern.fullmatch("doggie", 1, 3) # Совпадения в заданных пределах.1101<_sre.SRE_Match object; span=(1, 3), match='og'>1102```11031104Новое в версии 3.4.11051106#### `regex.split(string, maxsplit=0)`11071108Идентична функции [`split()`](https://python-all.ru/3.5/library/re.html#re.split), но использует скомпилированный шаблон.11091110#### `regex.findall(string[, pos[, endpos]])`11111112Похожа на функцию [`findall()`](https://python-all.ru/3.5/library/re.html#re.findall), использует скомпилированный шаблон, но также принимает необязательные параметры *pos* и *endpos*, ограничивающие область поиска, как и для [`match()`](https://python-all.ru/3.5/library/re.html#re.match).11131114#### `regex.finditer(string[, pos[, endpos]])`11151116Похожа на функцию [`finditer()`](https://python-all.ru/3.5/library/re.html#re.finditer), использует скомпилированный шаблон, но также принимает необязательные параметры *pos* и *endpos*, ограничивающие область поиска, как и для [`match()`](https://python-all.ru/3.5/library/re.html#re.match).11171118#### `regex.sub(repl, string, count=0)`11191120Идентична функции [`sub()`](https://python-all.ru/3.5/library/re.html#re.sub), но использует скомпилированный шаблон.11211122#### `regex.subn(repl, string, count=0)`11231124Идентична функции [`subn()`](https://python-all.ru/3.5/library/re.html#re.subn), но использует скомпилированный шаблон.11251126#### `regex.flags`11271128Флаги сопоставления регулярного выражения. Это комбинация флагов, переданных в [`compile()`](https://python-all.ru/3.5/library/re.html#re.compile), любых встроенных флагов `(?...)` в шаблоне, а также неявных флагов, таких как `UNICODE`, если шаблон является строкой Unicode.11291130#### `regex.groups`11311132Количество захватываемых групп в шаблоне.11331134#### `regex.groupindex`11351136Словарь, сопоставляющий символические имена групп, определённые через `(?P<id>)`, с номерами групп. Словарь пуст, если в шаблоне не использовались символические группы.11371138#### `regex.pattern`11391140Строка шаблона, из которой был скомпилирован объект RE.11411142## 6.2.4. Объекты совпадений11431144Объекты Match всегда имеют булево значение `True`. Поскольку [`match()`](https://python-all.ru/3.5/library/re.html#re.regex.match) и [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search) возвращают `None` при отсутствии совпадения, можно проверить, было ли совпадение, с помощью простого выражения `if`:11451146```python1147match = re.search(pattern, string)1148if match:1149 process(match)1150```11511152Объекты сопоставления поддерживают следующие методы и атрибуты:11531154#### `match.expand(template)`11551156Возвращает строку, полученную путём подстановки обратной косой черты в строку шаблона *шаблон*, как это делает метод [`sub()`](https://python-all.ru/3.5/library/re.html#re.regex.sub). escape-последовательности, такие как `\n`, преобразуются в соответствующие символы, а числовые обратные ссылки (`\1`, `\2`) и именованные обратные ссылки (`\g<1>`, `\g<name>`) заменяются содержимым соответствующей группы.11571158Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.11591160#### `match.group([group1, ...])`11611162Возвращает одну или несколько подгрупп совпадения. Если передан один аргумент, результат – одна строка; если несколько аргументов, результат – кортеж из одного элемента на аргумент. Без аргументов *group1* по умолчанию равен нулю (возвращается всё совпадение). Если аргумент *groupN* равен нулю, соответствующее возвращаемое значение – вся совпавшая строка; если он в диапазоне \[1..99\], это строка, соответствующая группе в скобках с таким номером. Если номер группы отрицателен или больше числа групп, определённых в шаблоне, вызывается исключение [`IndexError`](https://python-all.ru/3.5/library/exceptions.html#IndexError). Если группа содержится в части шаблона, которая не совпала, соответствующий результат равен `None`. Если группа содержится в части шаблона, которая совпала несколько раз, возвращается последнее совпадение.11631164```python1165>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")1166>>> m.group(0) # Всё совпадение1167'Isaac Newton'1168>>> m.group(1) # Первая группа в скобках.1169'Isaac'1170>>> m.group(2) # Вторая группа в скобках.1171'Newton'1172>>> m.group(1, 2) # Несколько аргументов дают кортеж.1173('Isaac', 'Newton')1174```11751176Если регулярное выражение использует синтаксис `(?P<name>...)`, аргументы *groupN* также могут быть строками, идентифицирующими группы по их имени. Если строка не используется как имя группы в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.5/library/exceptions.html#IndexError).11771178Довольно сложный пример:11791180```python1181>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")1182>>> m.group('first_name')1183'Malcolm'1184>>> m.group('last_name')1185'Reynolds'1186```11871188Именованные группы также можно указывать по их индексу:11891190```python1191>>> m.group(1)1192'Malcolm'1193>>> m.group(2)1194'Reynolds'1195```11961197Если группа совпадает несколько раз, доступно только последнее совпадение:11981199```python1200>>> m = re.match(r"(..)+", "a1b2c3") # Совпадает 3 раза.1201>>> m.group(1) # Возвращает только последнее совпадение.1202'c3'1203```12041205#### `match.groups(default=None)`12061207Возвращает кортеж, содержащий все подгруппы совпадения, от 1 до количества групп в шаблоне. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`.12081209Например:12101211```python1212>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")1213>>> m.groups()1214('24', '1632')1215```12161217Если сделать десятичную часть и всё после неё необязательными, не все группы могут участвовать в совпадении. Эти группы по умолчанию будут `None`, если не задан аргумент *default*:12181219```python1220>>> m = re.match(r"(\d+)\.?(\d+)?", "24")1221>>> m.groups() # Вторая группа по умолчанию – None.1222('24', None)1223>>> m.groups('0') # Теперь вторая группа по умолчанию – '0'.1224('24', '0')1225```12261227#### `match.groupdict(default=None)`12281229Возвращает словарь, содержащий все *именованные* подгруппы совпадения, где ключами являются имена подгрупп. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`. Например:12301231```python1232>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")1233>>> m.groupdict()1234{'first_name': 'Malcolm', 'last_name': 'Reynolds'}1235```12361237#### `match.start([group])`12381239#### `match.end([group])`12401241Возвращает индексы начала и конца подстроки, совпавшей с *group*; *group* по умолчанию равен нулю (означает всю совпавшую подстроку). Возвращает `-1`, если *group* существует, но не участвовала в совпадении. Для объекта совпадения *m* и группы *g*, которая участвовала в совпадении, подстрока, совпавшая с группой *g* (эквивалентно `m.group(g)`) – это12421243```python1244m.string[m.start(g):m.end(g)]1245```12461247Обратите внимание, что `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.5/library/exceptions.html#IndexError).12481249Пример, который удалит *remove\_this* из адресов электронной почты:12501251```python1252>>> email = "tony@tiremove_thisger.net"1253>>> m = re.search("remove_this", email)1254>>> email[:m.start()] + email[m.end():]1255'tony@tiger.net'1256```12571258#### `match.span([group])`12591260Для совпадения *m* возвращает кортеж из двух элементов `(m.start(group), m.end(group))`. Обратите внимание, что если *group* не участвовала в совпадении, это `(-1, -1)`. *group* по умолчанию равен нулю (всё совпадение).12611262#### `match.pos`12631264Значение *pos*, которое было передано методу [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search) или [`match()`](https://python-all.ru/3.5/library/re.html#re.regex.match) объекта [regex object](https://python-all.ru/3.5/library/re.html#re-objects). Это индекс в строке, с которого движок регулярных выражений начал поиск совпадения.12651266#### `match.endpos`12671268Значение *endpos*, которое было передано методу [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search) или [`match()`](https://python-all.ru/3.5/library/re.html#re.regex.match) объекта [regex object](https://python-all.ru/3.5/library/re.html#re-objects). Это индекс в строке, за который движок регулярных выражений не выйдет.12691270#### `match.lastindex`12711272Целочисленный индекс последней совпавшей захватывающей группы или `None`, если ни одна группа не совпала. Например, выражения `(a)b`, `((a)(b))` и `((ab))` будут иметь `lastindex == 1`, если применить к строке `'ab'`, в то время как выражение `(a)(b)` будет иметь `lastindex == 2`, если применить к той же строке.12731274#### `match.lastgroup`12751276Имя последней совпавшей захватывающей группы или `None`, если группа не имела имени, или если ни одна группа не совпала.12771278#### `match.re`12791280Объект регулярного выражения, чей метод [`match()`](https://python-all.ru/3.5/library/re.html#re.regex.match) или [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search) создал этот экземпляр совпадения.12811282#### `match.string`12831284Строка, переданная в [`match()`](https://python-all.ru/3.5/library/re.html#re.regex.match) или [`search()`](https://python-all.ru/3.5/library/re.html#re.regex.search).12851286## 6.2.5. Примеры регулярных выражений12871288### 6.2.5.1. Проверка на пару12891290В этом примере используется следующая вспомогательная функция для более наглядного отображения объектов совпадения:12911292```python1293def displaymatch(match):1294 if match is None:1295 return None1296 return '<Match: %r, groups=%r>' % (match.group(), match.groups())1297```12981299Допустим, пишется программа для покера, где рука игрока представлена в виде строки из 5 символов, каждый символ обозначает карту: «a» – туз, «k» – король, «q» – дама, «j» – валет, «t» – десятка, а «2»–«9» – карты соответствующего достоинства.13001301Чтобы проверить, является ли заданная строка допустимой рукой, можно поступить следующим образом:13021303```python1304>>> valid = re.compile(r"^[a2-9tjqk]{5}$")1305>>> displaymatch(valid.match("akt5q")) # Допустимо.1306"<Match: 'akt5q', groups=()>"1307>>> displaymatch(valid.match("akt5e")) # Недопустимо.1308>>> displaymatch(valid.match("akt")) # Недопустимо.1309>>> displaymatch(valid.match("727ak")) # Допустимо.1310"<Match: '727ak', groups=()>"1311```13121313Последняя рука, `"727ak"`, содержала пару, то есть две карты одного достоинства. Чтобы найти такое совпадение с помощью регулярного выражения, можно использовать обратные ссылки следующим образом:13141315```python1316>>> pair = re.compile(r".*(.).*\1")1317>>> displaymatch(pair.match("717ak")) # Пара семёрок.1318"<Match: '717', groups=('7',)>"1319>>> displaymatch(pair.match("718ak")) # Нет пар.1320>>> displaymatch(pair.match("354aa")) # Пара тузов.1321"<Match: '354aa', groups=('a',)>"1322```13231324Чтобы узнать, из какой карты состоит пара, можно использовать метод [`group()`](https://python-all.ru/3.5/library/re.html#re.match.group) объекта совпадения следующим образом:13251326```pycon1327>>> pair.match("717ak").group(1)1328'7'13291330# Error because re.match() returns None, which doesn't have a group() method:1331>>> pair.match("718ak").group(1)1332Traceback (most recent call last):1333 File "<pyshell#23>", line 1, in <module>1334 re.match(r".*(.).*\1", "718ak").group(1)1335AttributeError: 'NoneType' object has no attribute 'group'13361337>>> pair.match("354aa").group(1)1338'a'1339```13401341### 6.2.5.2. Имитация scanf()13421343В Python на данный момент нет аналога `scanf()`. Регулярные выражения в целом мощнее, но и более многословны, чем строки формата `scanf()`. В таблице ниже приведены более или менее эквивалентные соответствия между токенами формата `scanf()` и регулярными выражениями.13441345| `scanf()` Токен | Регулярное выражение |1346| --- | --- |1347| `%c` | `.` |1348| `%5c` | `.{5}` |1349| `%d` | `[-+]?\d+` |1350| `%e`, `%E`, `%f`, `%g` | `[-+]?(\d+(\.\d*)?\|\.\d+)([eE][-+]?\d+)?` |1351| `%i` | `[-+]?(0[xX][\dA-Fa-f]+\|0[0-7]*\|\d+)` |1352| `%o` | `[-+]?[0-7]+` |1353| `%s` | `\S+` |1354| `%u` | `\d+` |1355| `%x`, `%X` | `[-+]?(0[xX])?[\dA-Fa-f]+` |13561357Чтобы извлечь имя файла и числа из строки вида13581359```python1360/usr/sbin/sendmail - 0 errors, 4 warnings1361```13621363можно использовать формат `scanf()`, например13641365```python1366%s - %d errors, %d warnings1367```13681369Эквивалентное регулярное выражение будет13701371```python1372(\S+) - (\d+) errors, (\d+) warnings1373```13741375### 6.2.5.3. Сравнение search() и match()13761377Python предлагает две разные примитивные операции на основе регулярных выражений: [`re.match()`](https://python-all.ru/3.5/library/re.html#re.match) проверяет совпадение только в начале строки, а [`re.search()`](https://python-all.ru/3.5/library/re.html#re.search) проверяет совпадение в любом месте строки (так по умолчанию работает Perl).13781379Например:13801381```python1382>>> re.match("c", "abcdef") # Нет совпадения.1383>>> re.search("c", "abcdef") # Совпадает.1384<_sre.SRE_Match object; span=(2, 3), match='c'>1385```13861387Регулярные выражения, начинающиеся с `'^'`, можно использовать с [`search()`](https://python-all.ru/3.5/library/re.html#re.search), чтобы ограничить совпадение началом строки:13881389```python1390>>> re.match("c", "abcdef") # Нет совпадения.1391>>> re.search("^c", "abcdef") # Нет совпадения.1392>>> re.search("^a", "abcdef") # Совпадает.1393<_sre.SRE_Match object; span=(0, 1), match='a'>1394```13951396Обратите внимание, однако, что в режиме [`MULTILINE`](https://python-all.ru/3.5/library/re.html#re.MULTILINE) [`match()`](https://python-all.ru/3.5/library/re.html#re.match) соответствует только началу строки, тогда как использование [`search()`](https://python-all.ru/3.5/library/re.html#re.search) с регулярным выражением, начинающимся с `'^'`, будет соответствовать началу каждой строки.13971398```python1399>>> re.match('X', 'A\nB\nX', re.MULTILINE) # Нет совпадения.1400>>> re.search('^X', 'A\nB\nX', re.MULTILINE) # Совпадает.1401<_sre.SRE_Match object; span=(4, 5), match='X'>1402```14031404### 6.2.5.4. Создание телефонной книги14051406[`split()`](https://python-all.ru/3.5/library/re.html#re.split) разделяет строку на список, разделённый переданным шаблоном. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые можно легко читать и изменять с помощью Python, как показано в следующем примере, создающем телефонную книгу.14071408Сначала – входные данные. Обычно они берутся из файла, здесь мы используем синтаксис тройных кавычек:14091410```python1411>>> text = """Ross McFluff: 834.345.1254 155 Elm Street1412...1413... Ronald Heathmore: 892.345.3428 436 Finley Avenue1414... Frank Burger: 925.541.7625 662 South Dogwood Way1415...1416...1417... Heather Albrecht: 548.326.4584 919 Park Place"""1418```14191420Записи разделяются одним или несколькими символами новой строки. Теперь преобразуем строку в список, где каждая непустая строка будет отдельной записью:14211422```pycon1423>>> entries = re.split("\n+", text)1424>>> entries1425['Ross McFluff: 834.345.1254 155 Elm Street',1426'Ronald Heathmore: 892.345.3428 436 Finley Avenue',1427'Frank Burger: 925.541.7625 662 South Dogwood Way',1428'Heather Albrecht: 548.326.4584 919 Park Place']1429```14301431Наконец, разделим каждую запись на список, содержащий имя, фамилию, номер телефона и адрес. Используем параметр `maxsplit` функции [`split()`](https://python-all.ru/3.5/library/re.html#re.split), потому что адрес содержит пробелы, которые являются нашим разделителем:14321433```pycon1434>>> [re.split(":? ", entry, 3) for entry in entries]1435[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],1436['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],1437['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],1438['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]1439```14401441Шаблон `:?` соответствует двоеточию после фамилии, поэтому оно не попадает в результирующий список. Задав значение `maxsplit` равным `4`, можно было бы отделить номер дома от названия улицы:14421443```pycon1444>>> [re.split(":? ", entry, 4) for entry in entries]1445[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],1446['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],1447['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],1448['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]1449```14501451### 6.2.5.5. Обработка текста14521453[`sub()`](https://python-all.ru/3.5/library/re.html#re.sub) заменяет каждое вхождение шаблона на строку или результат функции. Этот пример демонстрирует использование [`sub()`](https://python-all.ru/3.5/library/re.html#re.sub) с функцией для «мунгирования» текста, то есть случайного изменения порядка всех символов в каждом слове предложения, кроме первого и последнего:14541455```python1456>>> def repl(m):1457... inner_word = list(m.group(2))1458... random.shuffle(inner_word)1459... return m.group(1) + "".join(inner_word) + m.group(3)1460>>> text = "Professor Abdolmalek, please report your absences promptly."1461>>> re.sub(r"(\w)(\w+)(\w)", repl, text)1462'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'1463>>> re.sub(r"(\w)(\w+)(\w)", repl, text)1464'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'1465```14661467### 6.2.5.6. Поиск всех наречий14681469[`findall()`](https://python-all.ru/3.5/library/re.html#re.findall) совпадает со *всеми* вхождениями шаблона, а не только первое, как [`search()`](https://python-all.ru/3.5/library/re.html#re.search). Например, если бы кто-то был писателем и хотел найти все наречия в тексте, он мог бы использовать [`findall()`](https://python-all.ru/3.5/library/re.html#re.findall) следующим образом:14701471```python1472>>> text = "He was carefully disguised but captured quickly by police."1473>>> re.findall(r"\w+ly", text)1474['carefully', 'quickly']1475```14761477### 6.2.5.7. Поиск всех наречий и их позиций14781479Если нужна бо́льшая информация о всех совпадениях шаблона, а не только о совпавшем тексте, [`finditer()`](https://python-all.ru/3.5/library/re.html#re.finditer) полезен, так как возвращает [объекты совпадений](https://python-all.ru/3.5/library/re.html#match-objects) вместо строк. Продолжая предыдущий пример, если бы нужно было найти все наречия *и их позиции* в тексте, можно было бы использовать [`finditer()`](https://python-all.ru/3.5/library/re.html#re.finditer) следующим образом:14801481```python1482>>> text = "He was carefully disguised but captured quickly by police."1483>>> for m in re.finditer(r"\w+ly", text):1484... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))148507-16: carefully148640-47: quickly1487```14881489### 6.2.5.8. Сырые строки14901491Нотация сырых строк (`r"text"`) сохраняет регулярные выражения в удобочитаемом виде. Без неё каждый обратный слеш (`'\'`) в регулярном выражении пришлось бы экранировать ещё одним таким же слешем. Например, следующие две строки кода функционально идентичны:14921493```python1494>>> re.match(r"\W(.)\1\W", " ff ")1495<_sre.SRE_Match object; span=(0, 4), match=' ff '>1496>>> re.match("\\W(.)\\1\\W", " ff ")1497<_sre.SRE_Match object; span=(0, 4), match=' ff '>1498```14991500Чтобы сопоставить буквальный обратный слеш, его нужно экранировать в регулярном выражении. В нотации сырых строк это означает `r"\\"`. Без нотации сырых строк нужно использовать `"\\\\"`, поэтому следующие строки кода функционально идентичны:15011502```python1503>>> re.match(r"\\", r"\\")1504<_sre.SRE_Match object; span=(0, 1), match='\\'>1505>>> re.match("\\\\", r"\\")1506<_sre.SRE_Match object; span=(0, 1), match='\\'>1507```15081509### 6.2.5.9. Написание токенизатора15101511[Токенизатор или сканер](https://python-all.ru/3.5/library/re.html) анализирует строку, чтобы разделить символы на группы. Это полезный первый шаг при написании компилятора или интерпретатора.15121513Категории текста задаются с помощью регулярных выражений. Метод заключается в том, чтобы объединить их в одно главное регулярное выражение и перебирать последовательные совпадения:15141515```python1516import collections1517import re15181519Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column'])15201521def tokenize(code):1522 keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}1523 token_specification = [1524 ('NUMBER', r'\d+(\.\d*)?'), # Целое или десятичное число.1525 ('ASSIGN', r':='), # Оператор присваивания.1526 ('END', r';'), # Терминатор инструкции.1527 ('ID', r'[A-Za-z]+'), # Идентификаторы.1528 ('OP', r'[+\-*/]'), # Арифметические операторы.1529 ('NEWLINE', r'\n'), # Концы строк.1530 ('SKIP', r'[ \t]+'), # Пропускать пробелы и табуляции.1531 ('MISMATCH',r'.'), # Любой другой символ.1532 ]1533 tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)1534 line_num = 11535 line_start = 01536 for mo in re.finditer(tok_regex, code):1537 kind = mo.lastgroup1538 value = mo.group(kind)1539 if kind == 'NEWLINE':1540 line_start = mo.end()1541 line_num += 11542 elif kind == 'SKIP':1543 pass1544 elif kind == 'MISMATCH':1545 raise RuntimeError('%r unexpected on line %d' % (value, line_num))1546 else:1547 if kind == 'ID' and value in keywords:1548 kind = value1549 column = mo.start() - line_start1550 yield Token(kind, value, line_num, column)15511552statements = '''1553 IF quantity THEN1554 total := total + price * quantity;1555 tax := price * 0.05;1556 ENDIF;1557'''15581559for token in tokenize(statements):1560 print(token)1561```15621563Токенизатор выдаёт следующий результат:15641565```python1566Token(typ='IF', value='IF', line=2, column=4)1567Token(typ='ID', value='quantity', line=2, column=7)1568Token(typ='THEN', value='THEN', line=2, column=16)1569Token(typ='ID', value='total', line=3, column=8)1570Token(typ='ASSIGN', value=':=', line=3, column=14)1571Token(typ='ID', value='total', line=3, column=17)1572Token(typ='OP', value='+', line=3, column=23)1573Token(typ='ID', value='price', line=3, column=25)1574Token(typ='OP', value='*', line=3, column=31)1575Token(typ='ID', value='quantity', line=3, column=33)1576Token(typ='END', value=';', line=3, column=41)1577Token(typ='ID', value='tax', line=4, column=8)1578Token(typ='ASSIGN', value=':=', line=4, column=12)1579Token(typ='ID', value='price', line=4, column=15)1580Token(typ='OP', value='*', line=4, column=21)1581Token(typ='NUMBER', value='0.05', line=4, column=23)1582Token(typ='END', value=';', line=4, column=27)1583Token(typ='ENDIF', value='ENDIF', line=5, column=4)1584Token(typ='END', value=';', line=5, column=9)1585```1586