Документация Python неофициальный перевод

re.md

1107 строк · 101.6 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.8/library/re.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`re`](https://python-all.ru/3.8/library/re.html#module-re) – Операции с регулярными выражениями89**Исходный код:** [Lib/re.py](https://python-all.ru/src/3.8/Lib/re.py)1011---1213Этот модуль предоставляет операции сопоставления с регулярными выражениями, аналогичные тем, что есть в Perl.1415И шаблоны, и строки для поиска могут быть строками Unicode ([`str`](https://python-all.ru/3.8/library/stdtypes.html#str)) , а также 8-битными строками ([`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes)). Однако строки Unicode и 8-битные строки нельзя смешивать: то есть нельзя сопоставлять строку Unicode с байтовым шаблоном или наоборот; аналогично, при запросе подстановки строка замены должна быть того же типа, что и шаблон, и искомая строка.1617Регулярные выражения используют символ обратной косой черты (`'\'`) для обозначения специальных форм или для использования специальных символов без вызова их специального значения. Это конфликтует с использованием того же символа в Python для той же цели в строковых литералах; например, для сопоставления буквальной обратной косой черты может потребоваться написать `'\\\\'` как шаблонную строку, потому что регулярное выражение должно быть `\\`, и каждая обратная косая черта должна быть выражена как `\\` внутри обычного строкового литерала Python. Также обратите внимание, что любые недопустимые escape-последовательности при использовании обратной косой черты в строковых литералах Python теперь порождают [`DeprecationWarning`](https://python-all.ru/3.8/library/exceptions.html#DeprecationWarning) и в будущем это станет [`SyntaxError`](https://python-all.ru/3.8/library/exceptions.html#SyntaxError). Это поведение будет иметь место, даже если это допустимая escape-последовательность для регулярного выражения.1819Решение – использовать сырые строки Python для шаблонов регулярных выражений; обратные косые черты не обрабатываются особым образом в строковых литералах с префиксом `'r'`. Таким образом, `r"\n"` – это строка из двух символов, содержащая `'\'` и `'n'`, тогда как `"\n"` – это строка из одного символа, содержащая символ новой строки. Обычно шаблоны выражаются в коде Python с использованием этой нотации сырых строк.2021Важно отметить, что большинство операций с регулярными выражениями доступны как функции уровня модуля и методы [скомпилированных регулярных выражений](https://python-all.ru/3.8/library/re.html#re-objects). Функции – это ярлыки, которые не требуют предварительной компиляции объекта regex, но не имеют некоторых параметров тонкой настройки.2223> **См. также**24>25> Сторонний модуль [regex](https://python-all.ru/3.8/library/re.html), API которого совместим с модулем стандартной библиотеки [`re`](https://python-all.ru/3.8/library/re.html#module-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.8/library/re.html#frie09), или почти в любом учебнике по конструированию компиляторов.3233Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более доступного изложения обратитесь к [руководству по регулярным выражениям](https://python-all.ru/3.8/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.8/library/re.html#re.DOTALL), то соответствует любому символу, включая символ новой строки.4647**`^`**4849(Циркумфлекс.) Соответствует началу строки, а в режиме [`MULTILINE`](https://python-all.ru/3.8/library/re.html#re.MULTILINE) также соответствует сразу после каждого символа новой строки.5051**`$`**5253Соответствует концу строки или непосредственно перед символом новой строки в конце строки, а в режиме [`MULTILINE`](https://python-all.ru/3.8/library/re.html#re.MULTILINE) также соответствует перед символом новой строки. `foo` соответствует и ‘foo’, и ‘foobar’, в то время как регулярное выражение `foo$` соответствует только ‘foo’. Интереснее то, что поиск `foo.$` в `'foo1\nfoo2\n'` обычно соответствует ‘foo2’, но в режиме [`MULTILINE`](https://python-all.ru/3.8/library/re.html#re.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Квантификаторы `'*'`, `'+'` и `'?'` являются *жадными*; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если РВ `<.*>` сопоставить с `'<a> b <c>'`, оно будет соответствовать всей строке, а не только `'<a>'`. Добавление `?` после квантификатора заставляет его выполнять сопоставление в *нежадном* или *минимальном* режиме; будет сопоставлено как *можно меньше* символов. Использование РВ `<.*?>` будет соответствовать только `'<a>'`.7071**`{m}`**7273Указывает, что должно быть сопоставлено ровно *m* копий предыдущего RE; меньшее количество совпадений приводит к тому, что всё RE не соответствует. Например, `a{6}` будет соответствовать ровно шести символам `'a'`, но не пяти.7475**`{m,n}`**7677Заставляет результирующее RE соответствовать от *m* до *n* повторений предыдущего RE, пытаясь сопоставить как можно больше повторений. Например, `a{3,5}` будет соответствовать от 3 до 5 символов `'a'`. Пропуск *m* задаёт нижнюю границу, равную нулю, а пропуск *n* задаёт бесконечную верхнюю границу. В качестве примера, `a{4,}b` будет соответствовать `'aaaab'` или тысяче символов `'a'`, за которыми следует `'b'`, но не `'aaab'`. Запятую нельзя опускать, иначе модификатор будет спутан с ранее описанной формой.7879**`{m,n}?`**8081Заставляет результирующее РВ соответствовать от *m* до *n* повторений предыдущего РВ, пытаясь сопоставить как *можно меньше* повторений. Это нежадная версия предыдущего квантификатора. Например, для 6-символьной строки `'aaaaaa'`, `a{3,5}` будет соответствовать 5 `'a'` символам, в то время как `a{3,5}?` будет соответствовать только 3 символам.8283**`\`**8485Либо экранирует специальные символы (позволяя сопоставлять такие символы, как `'*'`, `'?'` и т.д.), либо обозначает специальную последовательность; специальные последовательности рассматриваются ниже.8687Если вы не используете сырую строку для выражения шаблона, помните, что Python также использует обратную косую черту как escape-последовательность в строковых литералах; если escape- последовательность не распознаётся парсером Python, обратная косая черта и следующий за ней символ включаются в результирующую строку. Однако если Python распознает результирующую последовательность, обратную косую черту следует удвоить. Это сложно и трудно для понимания, поэтому настоятельно рекомендуется использовать сырые строки для всех, кроме самых простых выражений.8889**`[]`**9091Используется для обозначения набора символов. В наборе:9293- Символы можно перечислять по отдельности, например, `[amk]` совпадет с `'a'`, `'m'` или `'k'`.9495- Диапазоны символов можно указать, задав два символа и разделив их `'-'`, например `[a-z]` совпадет с любой строчной буквой ASCII, `[0-5][0-9]` – со всеми двузначными числами от `00` до `59`, а `[0-9A-Fa-f]` – с любой шестнадцатеричной цифрой. Если `-` экранирован (например, `[a\-z]`) или стоит первым или последним символом (например, `[-a]` или `[a-]`), он будет совпадать с литералом `'-'`.96- Специальные символы теряют своё специальное значение внутри наборов. Например, `[(+*)]` будет соответствовать любому из литеральных символов `'('`, `'+'`, `'*'` или `')'`.9798- Классы символов, такие как `\w` или `\S` (определены ниже), также принимаются внутри набора, хотя символы, которым они соответствуют, зависят от того, активен ли режим [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII) или [`LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE).99100- Символы, не входящие в диапазон, можно сопоставить с помощью *дополнения* набора. Если первый символ набора – `'^'`, то будут сопоставлены все символы, которые *не* входят в набор. Например, `[^5]` совпадет с любым символом, кроме `'5'`, а `[^^]` – с любым символом, кроме `'^'`. `^` не имеет специального значения, если он не первый символ в наборе.101- Чтобы найти символ `']'` внутри набора, поставьте перед ним обратную косую черту или поместите его в начало набора. Например, `[()[\]{}]` и `[]()[{}]` оба соответствуют круглой скобке.102103- Поддержка вложенных наборов и операций над наборами, как в [Unicode Technical Standard #18](https://python-all.ru/3.8/library/re.html), может быть добавлена в будущем. Это изменит синтаксис, поэтому для облегчения этого изменения в настоящее время в неоднозначных случаях будет вызываться [`FutureWarning`](https://python-all.ru/3.8/library/exceptions.html#FutureWarning). Сюда входят наборы, начинающиеся с литерала `'['` или содержащие литеральные последовательности символов `'--'`, `'&&'`, `'~~'` и `'||'`. Чтобы избежать предупреждения, экранируйте их обратной косой чертой.104105Изменено в версии 3.7: [`FutureWarning`](https://python-all.ru/3.8/library/exceptions.html#FutureWarning) вызывается, если набор символов содержит конструкции, которые в будущем изменят семантику.106107**`|`**108109`A|B`, где *A* и *B* могут быть произвольными РВ, создаёт регулярное выражение, которое совпадает либо с *A*, либо с *B*. Таким образом можно разделить произвольное количество РВ с помощью `'|'`. Это также можно использовать внутри групп (см. ниже). По мере сканирования целевой строки РВ, разделённые `'|'`, пробуются слева направо. Когда один шаблон полностью совпадает, эта ветвь принимается. Это означает, что как только *A* совпадает, *B* больше не проверяется, даже если бы оно дало более длинное общее совпадение. Другими словами, оператор `'|'` никогда не является жадным. Чтобы сопоставить литерал `'|'`, используйте `\|` или заключите его в класс символов, например `[|]`.110111**`(...)`**112113Соответствует любому регулярному выражению внутри круглых скобок и обозначает начало и конец группы; содержимое группы можно получить после выполнения сопоставления, а также сопоставить позже в строке с помощью специальной последовательности `\number`, описанной ниже. Чтобы сопоставить литералы `'('` или `')'`, используйте `\(` или `\)` или заключите их в класс символов: `[(]`, `[)]`.114115**`(?...)`**116117Это расширенная запись (иначе `'?'` после `'('` не имеет смысла). Первый символ после `'?'` определяет значение и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу; `(?P<name>...)` – единственное исключение из этого правила. Ниже перечислены поддерживаемые в настоящее время расширения.118119**`(?aiLmsux)`**120121(Одна или более букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`.) Группа соответствует пустой строке; буквы устанавливают соответствующие флаги: [`re.A`](https://python-all.ru/3.8/library/re.html#re.A) (только ASCII), [`re.I`](https://python-all.ru/3.8/library/re.html#re.I) (игнорировать регистр), [`re.L`](https://python-all.ru/3.8/library/re.html#re.L) (зависит от локали), [`re.M`](https://python-all.ru/3.8/library/re.html#re.M) (многострочный), [`re.S`](https://python-all.ru/3.8/library/re.html#re.S) (точка соответствует всему), `re.U` (сопоставление Unicode) и [`re.X`](https://python-all.ru/3.8/library/re.html#re.X) (подробный), для всего регулярного выражения. (Флаги описаны в разделе [Содержание модуля](https://python-all.ru/3.8/library/re.html#contents-of-module-re).) Это полезно, если вы хотите включить флаги как часть регулярного выражения, вместо передачи аргумента *flag* в функцию [`re.compile()`](https://python-all.ru/3.8/library/re.html#re.compile). Флаги должны использоваться первыми в строке выражения.122123**`(?:...)`**124125Незапоминающая версия обычных круглых скобок. Совпадает с любым регулярным выражением внутри скобок, но подстрока, совпавшая с группой, *не может* быть извлечена после выполнения сопоставления или использована для ссылки позже в шаблоне.126127**`(?aiLmsux-imsx:...)`**128129(Ноль или более букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`, необязательно за которыми следует `'-'`, а затем одна или более букв из набора `'i'`, `'m'`, `'s'`, `'x'`.) Буквы устанавливают или снимают соответствующие флаги: [`re.A`](https://python-all.ru/3.8/library/re.html#re.A) (только ASCII), [`re.I`](https://python-all.ru/3.8/library/re.html#re.I) (игнорировать регистр), [`re.L`](https://python-all.ru/3.8/library/re.html#re.L) (зависит от локали), [`re.M`](https://python-all.ru/3.8/library/re.html#re.M) (многострочный), [`re.S`](https://python-all.ru/3.8/library/re.html#re.S) (точка соответствует всему), `re.U` (сопоставление Unicode), и [`re.X`](https://python-all.ru/3.8/library/re.html#re.X) (подробный), для части выражения. (Флаги описаны в разделе [Содержание модуля](https://python-all.ru/3.8/library/re.html#contents-of-module-re).)130131Буквы `'a'`, `'L'` и `'u'` являются взаимоисключающими при использовании в качестве встроенных флагов, поэтому их нельзя комбинировать или ставить после `'-'`. Вместо этого, когда одна из них появляется во встроенной группе, она переопределяет режим сопоставления в объемлющей группе. В шаблонах Unicode `(?a:...)` переключает на сопоставление только ASCII, а `(?u:...)` переключает на сопоставление Unicode (по умолчанию). В байтовых шаблонах `(?L:...)` переключает на сопоставление, зависящее от локали, а `(?a:...)` переключает на сопоставление только ASCII (по умолчанию). Это переопределение действует только для узкой встроенной группы, а исходный режим сопоставления восстанавливается за пределами группы.132133Новое в версии 3.6.134135Изменено в версии 3.7: Буквы `'a'`, `'L'` и `'u'` также могут использоваться в группе.136137**`(?P<name>...)`**138139Аналогично обычным круглым скобкам, но подстрока, совпавшая с группой, доступна по символическому имени группы *name*. Имена групп должны быть допустимыми идентификаторами Python, и каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является нумерованной группой, как если бы группа не была именованной.140141Именованные группы можно использовать в трех контекстах. Если шаблон `(?P<quote>['"]).*?(?P=quote)` (т.е. соответствие строке, заключенной в одинарные или двойные кавычки):142143| Контекст ссылки на группу «quote» | Способы ссылки на нее |144| --- | --- |145| в том же самом шаблоне | `(?P=quote)` (как показано) `\1` |146| при обработке объекта совпадения *m* | `m.group('quote')` `m.end('quote')` (и т.д.) |147| в строке, передаваемой в аргумент *repl* функции `re.sub()` | `\g<quote>` `\g<1>` `\1` |148149**`(?P=name)`**150151Обратная ссылка на именованную группу; соответствует любому тексту, который был найден ранее группой с именем *name*.152153**`(?#...)`**154155Комментарий; содержимое скобок просто игнорируется.156157**`(?=...)`**158159Совпадает, если `...` совпадает далее, но не потребляет ни одного символа строки. Это называется *опережающей проверкой*. Например, `Isaac (?=Asimov)` совпадет с `'Isaac '`, только если за ним следует `'Asimov'`.160161**`(?!...)`**162163Совпадает, если `...` не совпадает далее. Это *отрицательная опережающая проверка*. Например, `Isaac (?!Asimov)` совпадет с `'Isaac '`, только если за ним *не* следует `'Asimov'`.164165**`(?<=...)`**166167Совпадает, если текущей позиции в строке предшествует совпадение с `...`, которое заканчивается в текущей позиции. Это называется *положительной ретроспективной проверкой*. `(?<=abc)def` найдет совпадение в `'abcdef'`, поскольку ретроспективная проверка отступит на 3 символа и проверит, совпадает ли вложенный шаблон. Вложенный шаблон может соответствовать только строкам фиксированной длины, то есть `abc` или `a|b` разрешены, а `a*` и `a{3,4}` – нет. Обратите внимание, что шаблоны, начинающиеся с положительной ретроспективной проверки, не будут совпадать в начале искомой строки; скорее всего, следует использовать функцию [`search()`](https://python-all.ru/3.8/library/re.html#re.search), а не [`match()`](https://python-all.ru/3.8/library/re.html#re.match):168169```python170>>> import re171>>> m = re.search('(?<=abc)def', 'abcdef')172>>> m.group(0)173'def'174```175176Этот пример ищет слово, следующее за дефисом:177178```python179>>> m = re.search(r'(?<=-)\w+', 'spam-egg')180>>> m.group(0)181'egg'182```183184Изменено в версии 3.5: Добавлена поддержка ссылок на группы фиксированной длины.185186**`(?<!...)`**187188Совпадает, если текущей позиции в строке не предшествует совпадение с `...`. Это называется *отрицательной ретроспективной проверкой*. Аналогично положительным ретроспективным проверкам, вложенный шаблон может соответствовать только строкам фиксированной длины. Шаблоны, начинающиеся с отрицательной ретроспективной проверки, могут совпадать в начале искомой строки.189190**`(?(id/name)yes-pattern|no-pattern)`**191192Будет пытаться сопоставить с `yes-pattern`, если группа с заданным *id* или *именем* существует, и с `no-pattern` в противном случае. `no-pattern` необязателен и может быть опущен. Например, `(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)` – это неудачный шаблон для сопоставления email, который будет соответствовать `'<user@host.com>'`, а также `'user@host.com'`, но не `'<user@host.com'` и не `'user@host.com>'`.193194Специальные последовательности состоят из `'\'` и символа из списка ниже. Если обычный символ не является цифрой ASCII или буквой ASCII, то полученное регулярное выражение будет соответствовать второму символу. Например, `\$` соответствует символу `'$'`.195196**`\number`**197198Совпадает с содержимым группы с тем же номером. Группы нумеруются начиная с 1. Например, `(.+) \1` совпадает с `'the the'` или `'55 55'`, но не с `'thethe'` (обратите внимание на пробел после группы). Эта специальная последовательность может использоваться только для сопоставления с одной из первых 99 групп. Если первая цифра *числа* равна 0, или *число* состоит из 3 восьмеричных цифр, оно не будет интерпретироваться как ссылка на группу, а как символ с восьмеричным значением *числа*. Внутри `'['` и `']'` символьного класса все числовые управляющие последовательности рассматриваются как символы.199200**`\A`**201202Совпадает только в начале строки.203204**`\b`**205206Соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность словообразовательных символов. Обратите внимание, что формально `\b` определяется как граница между символом `\w` и символом `\W` (или наоборот), или между `\w` и началом/концом строки. Это означает, что `r'\bfoo\b'` соответствует `'foo'`, `'foo.'`, `'(foo)'`, `'bar foo baz'`, но не `'foobar'` или `'foo3'`.207208По умолчанию в шаблонах Unicode используются буквенно-цифровые символы Unicode, но это можно изменить с помощью флага [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII). Границы слов определяются текущей локалью, если используется флаг [`LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE). Внутри диапазона символов `\b` представляет символ возврата на одну позицию (backspace) для совместимости со строковыми литералами Python.209210**`\B`**211212Соответствует пустой строке, но только когда она *не* находится в начале или конце слова. Это означает, что `r'py\B'` соответствует `'python'`, `'py3'`, `'py2'`, но не `'py'`, `'py.'` или `'py!'`. `\B` является противоположностью `\b`, поэтому словообразовательные символы в шаблонах Unicode являются буквенно-цифровыми символами Unicode или подчеркиванием, хотя это можно изменить с помощью флага [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII). Границы слов определяются текущей локалью, если используется флаг [`LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE).213214**`\d`**215216**Для шаблонов Unicode (str):**217218Соответствует любой десятичной цифре Unicode (то есть любому символу из категории символов Unicode \[Nd\]). Сюда входит `[0-9]`, а также многие другие цифровые символы. Если используется флаг [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII), то соответствует только `[0-9]`.219220**Для 8-битных (байтовых) шаблонов:**221222Соответствует любой десятичной цифре; это эквивалентно `[0-9]`.223224**`\D`**225226Соответствует любому символу, который не является десятичной цифрой. Это противоположность `\d`. Если используется флаг [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII), это становится эквивалентом `[^0-9]`.227228**`\s`**229230**Для шаблонов Unicode (str):**231232Соответствует пробельным символам Unicode (включая `[ \t\n\r\f\v]`, а также многие другие символы, например, неразрывные пробелы, предусмотренные типографскими правилами во многих языках). Если используется флаг [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII), то соответствует только `[ \t\n\r\f\v]`.233234**Для 8-битных (байтовых) шаблонов:**235236Соответствует символам, считающимся пробельными в наборе символов ASCII; это эквивалентно `[ \t\n\r\f\v]`.237238**`\S`**239240Соответствует любому символу, который не является пробельным. Это противоположность `\s`. Если используется флаг [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII), это становится эквивалентом `[^ \t\n\r\f\v]`.241242**`\w`**243244**Для шаблонов Unicode (str):**245246Соответствует буквенным символам Юникода; сюда входят большинство символов, которые могут быть частью слова в любом языке, а также цифры и символ подчёркивания. Если используется флаг [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII), то соответствует только `[a-zA-Z0-9_]`.247248**Для 8-битных (байтовых) шаблонов:**249250Соответствует символам, считающимся буквенно-цифровыми в наборе символов ASCII; это эквивалентно `[a-zA-Z0-9_]`. Если используется флаг [`LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE), то соответствует символам, считающимся буквенно-цифровыми в текущей локали, и символу подчеркивания.251252**`\W`**253254Соответствует любому символу, который не является словообразовательным. Это противоположность `\w`. Если используется флаг [`ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII), это становится эквивалентом `[^a-zA-Z0-9_]`. Если используется флаг [`LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE), то соответствует символам, которые не являются ни буквенно-цифровыми в текущей локали, ни символом подчеркивания.255256**`\Z`**257258Совпадение только в конце строки.259260Большинство стандартных управляющих последовательностей, поддерживаемых строковыми литералами Python, также принимаются синтаксическим анализатором регулярных выражений:261262```python263\a      \b      \f      \n264\N      \r      \t      \u265\U      \v      \x      \\266```267268(Обратите внимание, что `\b` используется для обозначения границ слов, а означает «забой» только внутри символьных классов.)269270Управляющие последовательности `'\u'`, `'\U'` и `'\N'` распознаются только в шаблонах Unicode. В байтовых шаблонах они вызывают ошибку. Неизвестные escape-последовательности ASCII-букв зарезервированы для будущего использования и считаются ошибками.271272Восьмеричные управляющие последовательности поддерживаются в ограниченной форме. Если первая цифра – 0, или если есть три восьмеричных цифры, это считается восьмеричной управляющей последовательностью. В противном случае это ссылка на группу. Как и в строковых литералах, восьмеричные управляющие последовательности всегда имеют длину не более трёх цифр.273274Изменено в версии 3.3: Добавлены управляющие последовательности `'\u'` и `'\U'`.275276Изменено в версии 3.6: Неизвестные управляющие последовательности, состоящие из `'\'` и буквы ASCII, теперь вызывают ошибки.277278Изменено в версии 3.8: Добавлена управляющая последовательность `'\N{name}'`. Как и в строковых литералах, она раскрывается в именованный символ Unicode (например, `'\N{EM DASH}'`).279280## Содержимое модуля281282Модуль определяет несколько функций, констант и одно исключение. Некоторые из функций являются упрощёнными версиями полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используется скомпилированная форма.283284Изменено в версии 3.6: Константы флагов теперь являются экземплярами `RegexFlag`, который является подклассом [`enum.IntFlag`](https://python-all.ru/3.8/library/enum.html#enum.IntFlag).285286#### `re.compile(pattern, flags=0)`287288Компилирует шаблон регулярного выражения в [объект регулярного выражения](https://python-all.ru/3.8/library/re.html#re-objects), который можно использовать для сопоставления с помощью его методов [`match()`](https://python-all.ru/3.8/library/re.html#re.Pattern.match), [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search) и других, описанных ниже.289290Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые из следующих переменных, комбинируя их с помощью побитового ИЛИ (оператор `|`).291292Последовательность293294```python295prog = re.compile(pattern)296result = prog.match(string)297```298299эквивалентна300301```python302result = re.match(pattern, string)303```304305но использование [`re.compile()`](https://python-all.ru/3.8/library/re.html#re.compile) и сохранение полученного объекта регулярного выражения для повторного использования более эффективно, когда выражение будет использоваться несколько раз в одной программе.306307> **Примечание**308>309> Скомпилированные версии последних шаблонов, переданных в [`re.compile()`](https://python-all.ru/3.8/library/re.html#re.compile) и функции сопоставления уровня модуля, кешируются, поэтому программам, использующим лишь несколько регулярных выражений за раз, не нужно беспокоиться о компиляции регулярных выражений.310311#### `re.A`312313#### `re.ASCII`314315Заставляет `\w`, `\W`, `\b`, `\B`, `\d`, `\D`, `\s` и `\S` выполнять сопоставление только по ASCII вместо полного сопоставления Unicode. Это имеет смысл только для шаблонов Unicode и игнорируется для байтовых шаблонов. Соответствует встроенному флагу `(?a)`.316317Обратите внимание, что для обратной совместимости флаг `re.U` все еще существует (как и его синоним `re.UNICODE` и встроенный аналог `(?u)`), но они избыточны в Python 3, поскольку сопоставление по умолчанию для строк выполняется в Unicode (а сопоставление Unicode не допускается для байтов).318319#### `re.DEBUG`320321Отображает отладочную информацию о скомпилированном выражении. Нет соответствующего встроенного флага.322323#### `re.I`324325#### `re.IGNORECASE`326327Выполняет сопоставление без учета регистра; выражения типа `[A-Z]` также будут соответствовать строчным буквам. Полное сопоставление Unicode (например, `Ü` соответствует `ü`) также работает, если только флаг [`re.ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII) не используется для отключения не-ASCII сопоставлений. Текущая локаль не влияет на действие этого флага, если только не используется также флаг [`re.LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE). Соответствует встроенному флагу `(?i)`.328329Обратите внимание, что при использовании юникодных шаблонов `[a-z]` или `[A-Z]` в сочетании с флагом [`IGNORECASE`](https://python-all.ru/3.8/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.8/library/re.html#re.ASCII), сопоставляются только буквы от «a» до «z» и от «A» до «Z».330331#### `re.L`332333#### `re.LOCALE`334335Делает `\w`, `\W`, `\b`, `\B` и сопоставление без учета регистра зависимыми от текущей локали. Этот флаг можно использовать только с байтовыми шаблонами. Использование этого флага не рекомендуется, так как механизм локали очень ненадежен, он обрабатывает только одну «культуру» за раз и работает только с 8-битными локалями. Сопоставление Unicode уже включено по умолчанию в Python 3 для шаблонов Unicode (str) и может обрабатывать разные локали/языки. Соответствует встроенному флагу `(?L)`.336337Изменено в версии 3.6: [`re.LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE) можно использовать только с байтовыми шаблонами и он несовместим с [`re.ASCII`](https://python-all.ru/3.8/library/re.html#re.ASCII).338339Изменено в версии 3.7: Скомпилированные объекты регулярных выражений с флагом [`re.LOCALE`](https://python-all.ru/3.8/library/re.html#re.LOCALE) больше не зависят от локали на этапе компиляции. Только локаль на момент сопоставления влияет на результат сопоставления.340341#### `re.M`342343#### `re.MULTILINE`344345При указании символ шаблона `'^'` соответствует началу строки и началу каждой строки (сразу после каждого перевода строки); а символ шаблона `'$'` соответствует концу строки и концу каждой строки (сразу перед каждым переводом строки). По умолчанию `'^'` соответствует только началу строки, а `'$'` только концу строки и сразу перед переводом строки (если есть) в конце строки. Соответствует встроенному флагу `(?m)`.346347#### `re.S`348349#### `re.DOTALL`350351Заставляет специальный символ `'.'` соответствовать любому символу, включая перевод строки; без этого флага `'.'` будет соответствовать любому символу *кроме* перевода строки. Соответствует встроенному флагу `(?s)`.352353#### `re.X`354355#### `re.VERBOSE`356357Этот флаг позволяет писать регулярные выражения, которые выглядят лучше и читаются легче, позволяя визуально разделять логические секции шаблона и добавлять комментарии. Пробельные символы внутри шаблона игнорируются, за исключением случаев, когда они находятся внутри символьного класса, или перед ними стоит неэкранированная обратная косая черта, или внутри токенов, таких как `*?`, `(?:` или `(?P<...>`. Если строка содержит `#`, который не находится внутри символьного класса и не предварён неэкранированной обратной косой чертой, все символы от самого левого такого `#` до конца строки игнорируются.358359Это означает, что следующие два объекта регулярных выражений, которые сопоставляют десятичное число, функционально эквивалентны:360361```python362a = re.compile(r"""\d +  # the integral part363                   \.    # the decimal point364                   \d *  # some fractional digits""", re.X)365b = re.compile(r"\d+\.\d*")366```367368Соответствует встроенному флагу `(?x)`.369370#### `re.search(pattern, string, flags=0)`371372Просматривает строку *string* в поиске первой позиции, где регулярное выражение *pattern* даёт совпадение, и возвращает соответствующий [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска нулевого совпадения в какой-то точке строки.373374#### `re.match(pattern, string, flags=0)`375376Если ноль или более символов в начале строки *string* соответствуют регулярному выражению *pattern*, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.377378Обратите внимание, что даже в режиме [`MULTILINE`](https://python-all.ru/3.8/library/re.html#re.MULTILINE), [`re.match()`](https://python-all.ru/3.8/library/re.html#re.match) будет совпадать только в начале строки, а не в начале каждой строки.379380If you want to locate a match anywhere in *string*, use [`search()`](https://python-all.ru/3.8/library/re.html#re.search) instead (see also [search() vs. match()](https://python-all.ru/3.8/library/re.html#search-vs-match)).381382#### `re.fullmatch(pattern, string, flags=0)`383384Если вся строка *string* соответствует регулярному выражению *pattern*, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.385386Новое в версии 3.4.387388#### `re.split(pattern, string, maxsplit=0, flags=0)`389390Разделяет *string* по вхождениям *pattern*. Если в *pattern* используются захватывающие круглые скобки, то текст всех групп в шаблоне также возвращается как часть результирующего списка. Если *maxsplit* не равно нулю, то происходит не более *maxsplit* разбиений, а остаток строки возвращается как последний элемент списка.391392```python393>>> re.split(r'\W+', 'Words, words, words.')394['Words', 'words', 'words', '']395>>> re.split(r'(\W+)', 'Words, words, words.')396['Words', ', ', 'words', ', ', 'words', '.', '']397>>> re.split(r'\W+', 'Words, words, words.', 1)398['Words', 'words, words.']399>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)400['0', '3', '9']401```402403Если в разделителе есть захватывающие группы и он совпадает в начале строки, результат будет начинаться с пустой строки. То же самое относится и к концу строки:404405```python406>>> re.split(r'(\W+)', '...words, words...')407['', '...', 'words', ', ', 'words', '...', '']408```409410Таким образом, компоненты разделителя всегда находятся на одних и тех же относительных индексах в результирующем списке.411412Пустые совпадения для шаблона разделяют строку, только если они не примыкают к предыдущему пустому совпадению.413414```python415>>> re.split(r'\b', 'Words, words, words.')416['', 'Words', ', ', 'words', ', ', 'words', '.']417>>> re.split(r'\W*', '...words...')418['', '', 'w', 'o', 'r', 'd', 's', '', '']419>>> re.split(r'(\W*)', '...words...')420['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']421```422423Изменено в версии 3.1: Добавлен необязательный аргумент flags.424425Изменено в версии 3.7: Добавлена возможность разделения по шаблону, который может соответствовать пустой строке.426427#### `re.findall(pattern, string, flags=0)`428429Возвращает все непересекающиеся совпадения *pattern* в *string* в виде списка строк. *string* сканируется слева направо, совпадения возвращаются в порядке обнаружения. Если в шаблоне присутствуют одна или несколько групп, возвращается список групп; если групп больше одной, список будет состоять из кортежей. Пустые совпадения включаются в результат.430431Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.432433#### `re.finditer(pattern, string, flags=0)`434435Возвращает [итератор](https://python-all.ru/3.8/glossary.html#term-iterator), возвращающий [объекты сопоставления](https://python-all.ru/3.8/library/re.html#match-objects) по всем непересекающимся совпадениям для RE *pattern* в строке *string*. Строка *string* сканируется слева направо, и совпадения возвращаются в порядке обнаружения. Пустые совпадения включаются в результат.436437Изменено в версии 3.7: Непустые совпадения теперь могут начинаться сразу после предыдущего пустого совпадения.438439#### `re.sub(pattern, repl, string, count=0, flags=0)`440441Возвращает строку, полученную заменой крайних левых непересекающихся вхождений *pattern* в *string* на замену *repl*. Если шаблон не найден, возвращается *string* без изменений. *repl* может быть строкой или функцией; если это строка, все обратные слеши в ней обрабатываются. То есть `\n` преобразуется в символ новой строки, `\r` – в возврат каретки и так далее. Неизвестные управляющие последовательности из букв ASCII зарезервированы для будущего использования и считаются ошибками. Другие неизвестные последовательности, такие как `\&`, остаются без изменений. Обратные ссылки, например `\6`, заменяются подстрокой, соответствующей группе 6 в шаблоне. Например:442443```python444>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',445...        r'static PyObject*\npy_\1(void)\n{',446...        'def myfunc():')447'static PyObject*\npy_myfunc(void)\n{'448```449450Если *repl* является функцией, она вызывается для каждого непересекающегося вхождения *pattern*. Функция принимает единственный аргумент – [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects), и возвращает строку замены. Например:451452```python453>>> def dashrepl(matchobj):454...     if matchobj.group(0) == '-': return ' '455...     else: return '-'456>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')457'pro--gram files'458>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)459'Baked Beans & Spam'460```461462Шаблон может быть строкой или [объектом шаблона](https://python-all.ru/3.8/library/re.html#re-objects).463464Необязательный аргумент *count* – это максимальное количество вхождений шаблона, подлежащих замене; *count* должен быть неотрицательным целым числом. Если он опущен или равен нулю, заменяются все вхождения. Пустые совпадения для шаблона заменяются только в том случае, если они не примыкают к предыдущему пустому совпадению, поэтому `sub('x*', '-', 'abxd')` возвращает `'-a-b--d-'`.465466В строковых аргументах *repl*, помимо управляющих последовательностей и обратных ссылок, описанных выше, `\g<name>` использует подстроку, соответствующую группе с именем `name`, как определено синтаксисом `(?P<name>...)`. `\g<number>` использует соответствующий номер группы; таким образом, `\g<2>` эквивалентно `\2`, но не вызывает неоднозначности в такой замене, как `\g<2>0`. `\20` будет интерпретироваться как ссылка на группу 20, а не как ссылка на группу 2 с последующим литеральным символом `'0'`. Обратная ссылка `\g<0>` подставляет всю подстроку, соответствующую регулярному выражению.467468Изменено в версии 3.1: Добавлен необязательный аргумент flags.469470Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.471472Изменено в версии 3.6: Неизвестные управляющие последовательности в *pattern*, состоящие из `'\'` и буквы ASCII, теперь считаются ошибками.473474Изменено в версии 3.7: Неизвестные экранирования в *repl*, состоящие из `'\'` и ASCII-буквы, теперь вызывают ошибку.475476Изменено в версии 3.7: Пустые совпадения с шаблоном заменяются, если они примыкают к предыдущему непустому совпадению.477478#### `re.subn(pattern, repl, string, count=0, flags=0)`479480Выполняет ту же операцию, что и [`sub()`](https://python-all.ru/3.8/library/re.html#re.sub), но возвращает кортеж `(new_string, number_of_subs_made)`.481482Изменено в версии 3.1: Добавлен необязательный аргумент flags.483484Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.485486#### `re.escape(pattern)`487488Экранирует специальные символы в *pattern*. Это полезно, если нужно сопоставить произвольную литеральную строку, которая может содержать метасимволы регулярных выражений. Например:489490```python491>>> print(re.escape('http://www.python.org'))492http://www\.python\.org493494>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"495>>> print('[%s]+' % re.escape(legal_chars))496[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+497498>>> operators = ['+', '-', '*', '/', '**']499>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))500/|\-|\+|\*\*|\*501```502503Эта функция не должна использоваться для строки замены в [`sub()`](https://python-all.ru/3.8/library/re.html#re.sub) и [`subn()`](https://python-all.ru/3.8/library/re.html#re.subn), экранировать следует только обратную косую черту. Например:504505```python506>>> digits_re = r'\d+'507>>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'508>>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))509/usr/sbin/sendmail - \d+ errors, \d+ warnings510```511512Изменено в версии 3.3: Символ `'_'` больше не экранируется.513514Изменено в версии 3.7: Теперь экранируются только символы, которые могут иметь специальное значение в регулярном выражении. В результате `'!'`, `'"'`, `'%'`, `"'"`, `','`, `'/'`, `':'`, `';'`, `'<'`, `'='`, `'>'`, `'@'` и `` "`" `` больше не экранируются.515516#### `re.purge()`517518Очищает кэш регулярных выражений.519520#### `exception re.error(msg, pattern=None, pos=None)`521522Исключение возникает, когда переданная одной из функций строка не является корректным регулярным выражением (например, может содержать непарные скобки) или когда происходит другая ошибка во время компиляции или сопоставления. Если строка не содержит совпадений с шаблоном, это никогда не считается ошибкой. Экземпляр ошибки имеет следующие дополнительные атрибуты:523524#### `msg`525526Неформатированное сообщение об ошибке.527528#### `pattern`529530Шаблон регулярного выражения.531532#### `pos`533534Индекс в *pattern*, где произошла ошибка компиляции (может быть `None`).535536#### `lineno`537538Строка, соответствующая *pos* (может быть `None`).539540#### `colno`541542Столбец, соответствующий *pos* (может быть `None`).543544Изменено в версии 3.5: Добавлены дополнительные атрибуты.545546## Объекты регулярных выражений547548Скомпилированные объекты регулярных выражений поддерживают следующие методы и атрибуты:549550#### `Pattern.search(string[, pos[, endpos]])`551552Просматривает строку *string* в поиске первой позиции, где данное регулярное выражение даёт совпадение, и возвращает соответствующий [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска нулевого совпадения в какой-то точке строки.553554Необязательный второй параметр *pos* задаёт индекс в строке, с которого начинается поиск; по умолчанию `0`. Это не полностью эквивалентно срезу строки; символ шаблона `'^'` сопоставляется с реальным началом строки и с позициями сразу после символа новой строки, но не обязательно с индексом, с которого должен начинаться поиск.555556Необязательный параметр *endpos* ограничивает, как далеко будет просматриваться строка; считается, что строка имеет длину *endpos* символов, поэтому для совпадения будут просмотрены только символы от *pos* до `endpos - 1`. Если *endpos* меньше *pos*, совпадение не будет найдено; в противном случае, если *rx* – скомпилированный объект регулярного выражения, `rx.search(string, 0, 50)` эквивалентно `rx.search(string[:50], 0)`.557558```python559>>> pattern = re.compile("d")560>>> pattern.search("dog")     # Совпадение на индексе 0561<re.Match object; span=(0, 1), match='d'>562>>> pattern.search("dog", 1)  # Совпадения нет; поиск не включает "d"563```564565#### `Pattern.match(string[, pos[, endpos]])`566567Если ноль или более символов в *начале* строки *string* соответствуют данному регулярному выражению, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.568569Необязательные параметры *pos* и *endpos* имеют то же значение, что и для метода [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search).570571```python572>>> pattern = re.compile("o")573>>> pattern.match("dog")      # Совпадения нет, так как "o" не в начале строки "dog".574>>> pattern.match("dog", 1)   # Совпадение есть, так как "o" – второй символ строки "dog".575<re.Match object; span=(1, 2), match='o'>576```577578Если требуется найти совпадение в любом месте *string*, используйте [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search) (см. также [search() vs. match()](https://python-all.ru/3.8/library/re.html#search-vs-match)).579580#### `Pattern.fullmatch(string[, pos[, endpos]])`581582Если вся строка *string* соответствует данному регулярному выражению, возвращает соответствующий [объект сопоставления](https://python-all.ru/3.8/library/re.html#match-objects). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от нулевого совпадения.583584Необязательные параметры *pos* и *endpos* имеют то же значение, что и для метода [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search).585586```python587>>> pattern = re.compile("o[gh]")588>>> pattern.fullmatch("dog")      # Совпадения нет, так как "o" не в начале строки "dog".589>>> pattern.fullmatch("ogre")     # Совпадения нет, так как не вся строка совпала.590>>> pattern.fullmatch("doggie", 1, 3)   # Совпадения в заданных пределах.591<re.Match object; span=(1, 3), match='og'>592```593594Новое в версии 3.4.595596#### `Pattern.split(string, maxsplit=0)`597598Идентична функции [`split()`](https://python-all.ru/3.8/library/re.html#re.split), но использует скомпилированный шаблон.599600#### `Pattern.findall(string[, pos[, endpos]])`601602Похожа на функцию [`findall()`](https://python-all.ru/3.8/library/re.html#re.findall), использует скомпилированный шаблон, но также принимает необязательные параметры *pos* и *endpos*, ограничивающие область поиска, как и для [`search()`](https://python-all.ru/3.8/library/re.html#re.search).603604#### `Pattern.finditer(string[, pos[, endpos]])`605606Похожа на функцию [`finditer()`](https://python-all.ru/3.8/library/re.html#re.finditer), использует скомпилированный шаблон, но также принимает необязательные параметры *pos* и *endpos*, ограничивающие область поиска, как и для [`search()`](https://python-all.ru/3.8/library/re.html#re.search).607608#### `Pattern.sub(repl, string, count=0)`609610Идентична функции [`sub()`](https://python-all.ru/3.8/library/re.html#re.sub), но использует скомпилированный шаблон.611612#### `Pattern.subn(repl, string, count=0)`613614Идентична функции [`subn()`](https://python-all.ru/3.8/library/re.html#re.subn), но использует скомпилированный шаблон.615616#### `Pattern.flags`617618Флаги сопоставления регулярного выражения. Это комбинация флагов, переданных в [`compile()`](https://python-all.ru/3.8/library/re.html#re.compile), любых встроенных флагов `(?...)` в шаблоне, а также неявных флагов, таких как `UNICODE`, если шаблон является строкой Unicode.619620#### `Pattern.groups`621622Количество захватываемых групп в шаблоне.623624#### `Pattern.groupindex`625626Словарь, сопоставляющий символические имена групп, определённые через `(?P<id>)`, с номерами групп. Словарь пуст, если в шаблоне не использовались символические группы.627628#### `Pattern.pattern`629630Строка шаблона, из которой был скомпилирован объект шаблона.631632Изменено в версии 3.7: Добавлена поддержка [`copy.copy()`](https://python-all.ru/3.8/library/copy.html#copy.copy) и [`copy.deepcopy()`](https://python-all.ru/3.8/library/copy.html#copy.deepcopy). Скомпилированные объекты регулярных выражений считаются атомарными.633634## Объекты Match635636Объекты Match всегда имеют булево значение `True`. Поскольку [`match()`](https://python-all.ru/3.8/library/re.html#re.Pattern.match) и [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search) возвращают `None` при отсутствии совпадения, можно проверить, было ли совпадение, с помощью простого выражения `if`:637638```python639match = re.search(pattern, string)640if match:641    process(match)642```643644Объекты сопоставления поддерживают следующие методы и атрибуты:645646#### `Match.expand(template)`647648Возвращает строку, полученную путём подстановки обратной косой черты в строку шаблона *шаблон*, как это делает метод [`sub()`](https://python-all.ru/3.8/library/re.html#re.Pattern.sub). escape-последовательности, такие как `\n`, преобразуются в соответствующие символы, а числовые обратные ссылки (`\1`, `\2`) и именованные обратные ссылки (`\g<1>`, `\g<name>`) заменяются содержимым соответствующей группы.649650Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.651652#### `Match.group([group1, ...])`653654Возвращает одну или несколько подгрупп совпадения. Если передан один аргумент, результат – одна строка; если несколько аргументов, результат – кортеж из одного элемента на аргумент. Без аргументов *group1* по умолчанию равен нулю (возвращается всё совпадение). Если аргумент *groupN* равен нулю, соответствующее возвращаемое значение – вся совпавшая строка; если он в диапазоне \[1..99\], это строка, соответствующая группе в скобках с таким номером. Если номер группы отрицателен или больше числа групп, определённых в шаблоне, вызывается исключение [`IndexError`](https://python-all.ru/3.8/library/exceptions.html#IndexError). Если группа содержится в части шаблона, которая не совпала, соответствующий результат равен `None`. Если группа содержится в части шаблона, которая совпала несколько раз, возвращается последнее совпадение.655656```python657>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")658>>> m.group(0)       # Всё совпадение659'Isaac Newton'660>>> m.group(1)       # Первая группа в скобках.661'Isaac'662>>> m.group(2)       # Вторая группа в скобках.663'Newton'664>>> m.group(1, 2)    # Несколько аргументов дают кортеж.665('Isaac', 'Newton')666```667668Если регулярное выражение использует синтаксис `(?P<name>...)`, аргументы *groupN* также могут быть строками, идентифицирующими группы по их имени. Если строка не используется как имя группы в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.8/library/exceptions.html#IndexError).669670Довольно сложный пример:671672```python673>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")674>>> m.group('first_name')675'Malcolm'676>>> m.group('last_name')677'Reynolds'678```679680Именованные группы также можно указывать по их индексу:681682```python683>>> m.group(1)684'Malcolm'685>>> m.group(2)686'Reynolds'687```688689Если группа совпадает несколько раз, доступно только последнее совпадение:690691```python692>>> m = re.match(r"(..)+", "a1b2c3")  # Совпадает 3 раза.693>>> m.group(1)                        # Возвращает только последнее совпадение.694'c3'695```696697#### `Match.__getitem__(g)`698699Это идентично `m.group(g)`. Это упрощает доступ к отдельной группе из совпадения:700701```python702>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")703>>> m[0]       # Всё совпадение704'Isaac Newton'705>>> m[1]       # Первая группа в скобках.706'Isaac'707>>> m[2]       # Вторая группа в скобках.708'Newton'709```710711Новое в версии 3.6.712713#### `Match.groups(default=None)`714715Возвращает кортеж, содержащий все подгруппы совпадения, от 1 до количества групп в шаблоне. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`.716717Например:718719```python720>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")721>>> m.groups()722('24', '1632')723```724725Если сделать десятичную часть и всё после неё необязательными, не все группы могут участвовать в совпадении. Эти группы по умолчанию будут `None`, если не задан аргумент *default*:726727```python728>>> m = re.match(r"(\d+)\.?(\d+)?", "24")729>>> m.groups()      # Вторая группа по умолчанию – None.730('24', None)731>>> m.groups('0')   # Теперь вторая группа по умолчанию – '0'.732('24', '0')733```734735#### `Match.groupdict(default=None)`736737Возвращает словарь, содержащий все *именованные* подгруппы совпадения, где ключами являются имена подгрупп. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`. Например:738739```python740>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")741>>> m.groupdict()742{'first_name': 'Malcolm', 'last_name': 'Reynolds'}743```744745#### `Match.start([group])`746747#### `Match.end([group])`748749Возвращает индексы начала и конца подстроки, совпавшей с *group*; *group* по умолчанию равен нулю (означает всю совпавшую подстроку). Возвращает `-1`, если *group* существует, но не участвовала в совпадении. Для объекта совпадения *m* и группы *g*, которая участвовала в совпадении, подстрока, совпавшая с группой *g* (эквивалентно `m.group(g)`) – это750751```python752m.string[m.start(g):m.end(g)]753```754755Обратите внимание, что `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.8/library/exceptions.html#IndexError).756757Пример, который удалит *remove\_this* из адресов электронной почты:758759```python760>>> email = "tony@tiremove_thisger.net"761>>> m = re.search("remove_this", email)762>>> email[:m.start()] + email[m.end():]763'tony@tiger.net'764```765766#### `Match.span([group])`767768Для совпадения *m* возвращает кортеж из двух элементов `(m.start(group), m.end(group))`. Обратите внимание, что если *group* не участвовала в совпадении, это `(-1, -1)`. *group* по умолчанию равен нулю (всё совпадение).769770#### `Match.pos`771772Значение *pos*, которое было передано методу [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search) или [`match()`](https://python-all.ru/3.8/library/re.html#re.Pattern.match) объекта [regex object](https://python-all.ru/3.8/library/re.html#re-objects). Это индекс в строке, с которого движок регулярных выражений начал поиск совпадения.773774#### `Match.endpos`775776Значение *endpos*, которое было передано методу [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search) или [`match()`](https://python-all.ru/3.8/library/re.html#re.Pattern.match) объекта [regex object](https://python-all.ru/3.8/library/re.html#re-objects). Это индекс в строке, за который движок регулярных выражений не выйдет.777778#### `Match.lastindex`779780Целочисленный индекс последней совпавшей захватывающей группы или `None`, если ни одна группа не совпала. Например, выражения `(a)b`, `((a)(b))` и `((ab))` будут иметь `lastindex == 1`, если применить к строке `'ab'`, в то время как выражение `(a)(b)` будет иметь `lastindex == 2`, если применить к той же строке.781782#### `Match.lastgroup`783784Имя последней совпавшей захватывающей группы или `None`, если группа не имела имени, или если ни одна группа не совпала.785786#### `Match.re`787788[Объект регулярного выражения](https://python-all.ru/3.8/library/re.html#re-objects), чей метод [`match()`](https://python-all.ru/3.8/library/re.html#re.Pattern.match) или [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search) создал этот экземпляр совпадения.789790#### `Match.string`791792Строка, переданная в [`match()`](https://python-all.ru/3.8/library/re.html#re.Pattern.match) или [`search()`](https://python-all.ru/3.8/library/re.html#re.Pattern.search).793794Изменено в версии 3.7: Добавлена поддержка [`copy.copy()`](https://python-all.ru/3.8/library/copy.html#copy.copy) и [`copy.deepcopy()`](https://python-all.ru/3.8/library/copy.html#copy.deepcopy). Объекты Match считаются атомарными.795796## Примеры регулярных выражений797798### Проверка на пару799800В этом примере используется следующая вспомогательная функция для более наглядного отображения объектов совпадения:801802```python803def displaymatch(match):804    if match is None:805        return None806    return '<Match: %r, groups=%r>' % (match.group(), match.groups())807```808809Допустим, пишется программа для покера, где рука игрока представлена в виде строки из 5 символов, каждый символ обозначает карту: «a» – туз, «k» – король, «q» – дама, «j» – валет, «t» – десятка, а «2»–«9» – карты соответствующего достоинства.810811Чтобы проверить, является ли заданная строка допустимой рукой, можно поступить следующим образом:812813```python814>>> valid = re.compile(r"^[a2-9tjqk]{5}$")815>>> displaymatch(valid.match("akt5q"))  # Допустимо.816"<Match: 'akt5q', groups=()>"817>>> displaymatch(valid.match("akt5e"))  # Недопустимо.818>>> displaymatch(valid.match("akt"))    # Недопустимо.819>>> displaymatch(valid.match("727ak"))  # Допустимо.820"<Match: '727ak', groups=()>"821```822823Последняя рука, `"727ak"`, содержала пару, то есть две карты одного достоинства. Чтобы найти такое совпадение с помощью регулярного выражения, можно использовать обратные ссылки следующим образом:824825```python826>>> pair = re.compile(r".*(.).*\1")827>>> displaymatch(pair.match("717ak"))     # Пара семёрок.828"<Match: '717', groups=('7',)>"829>>> displaymatch(pair.match("718ak"))     # Нет пар.830>>> displaymatch(pair.match("354aa"))     # Пара тузов.831"<Match: '354aa', groups=('a',)>"832```833834Чтобы узнать, из какой карты состоит пара, можно использовать метод [`group()`](https://python-all.ru/3.8/library/re.html#re.Match.group) объекта совпадения следующим образом:835836```python837>>> pair = re.compile(r".*(.).*\1")838>>> pair.match("717ak").group(1)839'7'840841# Error because re.match() returns None, which doesn't have a group() method:842>>> pair.match("718ak").group(1)843Traceback (most recent call last):844  File "<pyshell#23>", line 1, in <module>845    re.match(r".*(.).*\1", "718ak").group(1)846AttributeError: 'NoneType' object has no attribute 'group'847848>>> pair.match("354aa").group(1)849'a'850```851852### Эмуляция scanf()853854В Python на данный момент нет аналога `scanf()`. Регулярные выражения в целом мощнее, но и более многословны, чем строки формата `scanf()`. В таблице ниже приведены более или менее эквивалентные соответствия между токенами формата `scanf()` и регулярными выражениями.855856| `scanf()` Токен | Регулярное выражение |857| --- | --- |858| `%c` | `.` |859| `%5c` | `.{5}` |860| `%d` | `[-+]?\d+` |861| `%e`, `%E`, `%f`, `%g` | `[-+]?(\d+(\.\d*)?\|\.\d+)([eE][-+]?\d+)?` |862| `%i` | `[-+]?(0[xX][\dA-Fa-f]+\|0[0-7]*\|\d+)` |863| `%o` | `[-+]?[0-7]+` |864| `%s` | `\S+` |865| `%u` | `\d+` |866| `%x`, `%X` | `[-+]?(0[xX])?[\dA-Fa-f]+` |867868Чтобы извлечь имя файла и числа из строки вида869870```python871/usr/sbin/sendmail - 0 errors, 4 warnings872```873874можно использовать формат `scanf()`, например875876```python877%s - %d errors, %d warnings878```879880Эквивалентное регулярное выражение будет881882```python883(\S+) - (\d+) errors, (\d+) warnings884```885886### search() и match()887888Python предлагает две разные примитивные операции на основе регулярных выражений: [`re.match()`](https://python-all.ru/3.8/library/re.html#re.match) проверяет совпадение только в начале строки, а [`re.search()`](https://python-all.ru/3.8/library/re.html#re.search) проверяет совпадение в любом месте строки (так по умолчанию работает Perl).889890Например:891892```python893>>> re.match("c", "abcdef")    # Нет совпадения.894>>> re.search("c", "abcdef")   # Совпадает.895<re.Match object; span=(2, 3), match='c'>896```897898Регулярные выражения, начинающиеся с `'^'`, можно использовать с [`search()`](https://python-all.ru/3.8/library/re.html#re.search), чтобы ограничить совпадение началом строки:899900```python901>>> re.match("c", "abcdef")    # Нет совпадения.902>>> re.search("^c", "abcdef")  # Нет совпадения.903>>> re.search("^a", "abcdef")  # Совпадает.904<re.Match object; span=(0, 1), match='a'>905```906907Обратите внимание, однако, что в режиме [`MULTILINE`](https://python-all.ru/3.8/library/re.html#re.MULTILINE) [`match()`](https://python-all.ru/3.8/library/re.html#re.match) соответствует только началу строки, тогда как использование [`search()`](https://python-all.ru/3.8/library/re.html#re.search) с регулярным выражением, начинающимся с `'^'`, будет соответствовать началу каждой строки.908909```python910>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # Нет совпадения.911>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Совпадает.912<re.Match object; span=(4, 5), match='X'>913```914915### Создание телефонной книги916917[`split()`](https://python-all.ru/3.8/library/re.html#re.split) разделяет строку на список, разделённый переданным шаблоном. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые можно легко читать и изменять с помощью Python, как показано в следующем примере, создающем телефонную книгу.918919Сначала приведём входные данные. Обычно они могут поступать из файла, здесь используется синтаксис строки в тройных кавычках.920921```pycon922>>> text = """Ross McFluff: 834.345.1254 155 Elm Street923...924... Ronald Heathmore: 892.345.3428 436 Finley Avenue925... Frank Burger: 925.541.7625 662 South Dogwood Way926...927...928... Heather Albrecht: 548.326.4584 919 Park Place"""929```930931Записи разделяются одним или несколькими символами новой строки. Теперь преобразуем строку в список, где каждая непустая строка будет отдельной записью:932933```pycon934>>> entries = re.split("\n+", text)935>>> entries936['Ross McFluff: 834.345.1254 155 Elm Street',937'Ronald Heathmore: 892.345.3428 436 Finley Avenue',938'Frank Burger: 925.541.7625 662 South Dogwood Way',939'Heather Albrecht: 548.326.4584 919 Park Place']940```941942Наконец, разделим каждую запись на список, содержащий имя, фамилию, номер телефона и адрес. Используем параметр `maxsplit` функции [`split()`](https://python-all.ru/3.8/library/re.html#re.split), потому что адрес содержит пробелы, которые являются нашим разделителем:943944```pycon945>>> [re.split(":? ", entry, 3) for entry in entries]946[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],947['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],948['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],949['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]950```951952Шаблон `:?` соответствует двоеточию после фамилии, поэтому оно не попадает в результирующий список. Задав значение `maxsplit` равным `4`, можно было бы отделить номер дома от названия улицы:953954```pycon955>>> [re.split(":? ", entry, 4) for entry in entries]956[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],957['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],958['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],959['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]960```961962### Обработка текста963964[`sub()`](https://python-all.ru/3.8/library/re.html#re.sub) заменяет каждое вхождение шаблона на строку или результат функции. Этот пример демонстрирует использование [`sub()`](https://python-all.ru/3.8/library/re.html#re.sub) с функцией для «мунгирования» текста, то есть случайного изменения порядка всех символов в каждом слове предложения, кроме первого и последнего:965966```python967>>> def repl(m):968...     inner_word = list(m.group(2))969...     random.shuffle(inner_word)970...     return m.group(1) + "".join(inner_word) + m.group(3)971>>> text = "Professor Abdolmalek, please report your absences promptly."972>>> re.sub(r"(\w)(\w+)(\w)", repl, text)973'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'974>>> re.sub(r"(\w)(\w+)(\w)", repl, text)975'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'976```977978### Поиск всех наречий979980[`findall()`](https://python-all.ru/3.8/library/re.html#re.findall) находит *все* вхождения шаблона, а не только первое, как [`search()`](https://python-all.ru/3.8/library/re.html#re.search). Например, если требуется найти все наречия в тексте, можно использовать [`findall()`](https://python-all.ru/3.8/library/re.html#re.findall) следующим образом:981982```python983>>> text = "He was carefully disguised but captured quickly by police."984>>> re.findall(r"\w+ly", text)985['carefully', 'quickly']986```987988### Поиск всех наречий и их позиций989990Если требуется получить больше информации о всех совпадениях шаблона, чем просто совпавший текст, [`finditer()`](https://python-all.ru/3.8/library/re.html#re.finditer) полезен, так как он возвращает [объекты совпадений](https://python-all.ru/3.8/library/re.html#match-objects) вместо строк. Продолжая предыдущий пример, если автору нужно найти все наречия *и их позиции* в тексте, он будет использовать [`finditer()`](https://python-all.ru/3.8/library/re.html#re.finditer) следующим образом:991992```python993>>> text = "He was carefully disguised but captured quickly by police."994>>> for m in re.finditer(r"\w+ly", text):995...     print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))99607-16: carefully99740-47: quickly998```9991000### Нотация сырых строк10011002Нотация сырых строк (`r"text"`) сохраняет регулярные выражения в удобочитаемом виде. Без неё каждый обратный слеш (`'\'`) в регулярном выражении пришлось бы экранировать ещё одним таким же слешем. Например, следующие две строки кода функционально идентичны:10031004```python1005>>> re.match(r"\W(.)\1\W", " ff ")1006<re.Match object; span=(0, 4), match=' ff '>1007>>> re.match("\\W(.)\\1\\W", " ff ")1008<re.Match object; span=(0, 4), match=' ff '>1009```10101011Чтобы сопоставить буквальный обратный слеш, его нужно экранировать в регулярном выражении. В нотации сырых строк это означает `r"\\"`. Без нотации сырых строк нужно использовать `"\\\\"`, поэтому следующие строки кода функционально идентичны:10121013```python1014>>> re.match(r"\\", r"\\")1015<re.Match object; span=(0, 1), match='\\'>1016>>> re.match("\\\\", r"\\")1017<re.Match object; span=(0, 1), match='\\'>1018```10191020### Написание токенизатора10211022[Токенизатор или сканер](https://python-all.ru/3.8/library/re.html) анализирует строку, чтобы разделить символы на группы. Это полезный первый шаг при написании компилятора или интерпретатора.10231024Категории текста задаются с помощью регулярных выражений. Метод заключается в том, чтобы объединить их в одно главное регулярное выражение и перебирать последовательные совпадения:10251026```python1027from typing import NamedTuple1028import re10291030class Token(NamedTuple):1031    type: str1032    value: str1033    line: int1034    column: int10351036def tokenize(code):1037    keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}1038    token_specification = [1039        ('NUMBER',   r'\d+(\.\d*)?'),  # Целое или десятичное число.1040        ('ASSIGN',   r':='),           # Оператор присваивания.1041        ('END',      r';'),            # Терминатор инструкции.1042        ('ID',       r'[A-Za-z]+'),    # Идентификаторы.1043        ('OP',       r'[+\-*/]'),      # Арифметические операторы.1044        ('NEWLINE',  r'\n'),           # Концы строк.1045        ('SKIP',     r'[ \t]+'),       # Пропускать пробелы и табуляции.1046        ('MISMATCH', r'.'),            # Любой другой символ.1047    ]1048    tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)1049    line_num = 11050    line_start = 01051    for mo in re.finditer(tok_regex, code):1052        kind = mo.lastgroup1053        value = mo.group()1054        column = mo.start() - line_start1055        if kind == 'NUMBER':1056            value = float(value) if '.' in value else int(value)1057        elif kind == 'ID' and value in keywords:1058            kind = value1059        elif kind == 'NEWLINE':1060            line_start = mo.end()1061            line_num += 11062            continue1063        elif kind == 'SKIP':1064            continue1065        elif kind == 'MISMATCH':1066            raise RuntimeError(f'{value!r} unexpected on line {line_num}')1067        yield Token(kind, value, line_num, column)10681069statements = '''1070    IF quantity THEN1071        total := total + price * quantity;1072        tax := price * 0.05;1073    ENDIF;1074'''10751076for token in tokenize(statements):1077    print(token)1078```10791080Токенизатор выдаёт следующий результат:10811082```python1083Token(type='IF', value='IF', line=2, column=4)1084Token(type='ID', value='quantity', line=2, column=7)1085Token(type='THEN', value='THEN', line=2, column=16)1086Token(type='ID', value='total', line=3, column=8)1087Token(type='ASSIGN', value=':=', line=3, column=14)1088Token(type='ID', value='total', line=3, column=17)1089Token(type='OP', value='+', line=3, column=23)1090Token(type='ID', value='price', line=3, column=25)1091Token(type='OP', value='*', line=3, column=31)1092Token(type='ID', value='quantity', line=3, column=33)1093Token(type='END', value=';', line=3, column=41)1094Token(type='ID', value='tax', line=4, column=8)1095Token(type='ASSIGN', value=':=', line=4, column=12)1096Token(type='ID', value='price', line=4, column=15)1097Token(type='OP', value='*', line=4, column=21)1098Token(type='NUMBER', value=0.05, line=4, column=23)1099Token(type='END', value=';', line=4, column=27)1100Token(type='ENDIF', value='ENDIF', line=5, column=4)1101Token(type='END', value=';', line=5, column=9)1102```11031104**[Frie09](https://python-all.ru/3.8/library/re.html#id1)**11051106Фридл, Джеффри. «Освоение регулярных выражений». 3-е изд., O’Reilly Media, 2009. Третье издание книги больше не рассматривает Python, но первое издание очень подробно освещает написание хороших шаблонов регулярных выражений.1107