re.md
1> **Источник:** https://python-all.ru/3.1/library/re.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 7.2. `re` – Операции с регулярными выражениями89Этот модуль предоставляет операции сопоставления с регулярными выражениями, аналогичные тем, что есть в Perl.1011И паттерны, и искомые строки могут быть как строками Unicode, так и 8-битными строками. Однако строки Unicode и 8-битные строки нельзя смешивать: нельзя сопоставить строку Unicode с байтовым паттерном или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и паттерн, и искомая строка.1213В регулярных выражениях обратная косая черта (`'\'`) используется для обозначения специальных форм или чтобы разрешить использование специальных символов без их специального значения. Это противоречит использованию того же символа в Python для той же цели в строковых литералах; например, чтобы сопоставить буквальную обратную косую черту, возможно, придётся написать `'\\\\'` в строке шаблона, потому что регулярное выражение должно быть `\\`, а каждую обратную косую черту нужно выразить как `\\` внутри обычного строкового литерала Python.1415Решение – использовать raw-строки Python для паттернов регулярных выражений; обратная косая черта не обрабатывается особым образом в строковом литерале с префиксом `'r'`. Так что `r"\n"` – это двухсимвольная строка, содержащая `'\'` и `'n'`, в то время как `"\n"` – односимвольная строка, содержащая символ новой строки. Обычно паттерны записывают в коде Python с использованием этой raw-нотации.1617Важно отметить, что большинство операций с регулярными выражениями доступны в виде функций на уровне модуля и методов [`RegexObject`](https://python-all.ru/3.1/library/re.html#re.RegexObject). Эти функции являются сокращениями, которые не требуют предварительной компиляции объекта регулярного выражения, но не имеют некоторых параметров тонкой настройки.1819> **См. также**20>21> **Освоение регулярных выражений**22>23> Книга по регулярным выражениям Джеффри Фридла, издательство O’Reilly. Второе издание книги вообще не охватывает Python, но первое издание очень подробно описывает написание хороших шаблонов регулярных выражений.2425## 7.2.1. Синтаксис регулярных выражений2627Регулярное выражение (или RE) задаёт набор строк, которым оно соответствует; функции в этом модуле позволяют проверить, соответствует ли конкретная строка заданному регулярному выражению (или соответствует ли заданное регулярное выражение конкретной строке – что одно и то же).2829Регулярные выражения можно объединять для получения новых регулярных выражений; если *A* и *B* – регулярные выражения, то *AB* тоже регулярное выражение. В общем, если строка *p* соответствует *A*, а другая строка *q* соответствует *B*, то строка *pq* будет соответствовать AB. Это верно, если только *A* или *B* не содержат операций с низким приоритетом, граничных условий между *A* и *B* или нумерованных обращений к группам. Таким образом, сложные выражения легко строятся из более простых примитивных выражений, подобных описанным здесь. Подробнее о теории и реализации регулярных выражений см. книгу Фридла, указанную выше, или почти любой учебник по построению компиляторов.3031Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более доступного изложения обратитесь к [*руководству по регулярным выражениям*](https://python-all.ru/3.1/howto/regex.html#regex-howto).3233Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, например `'A'`, `'a'` или `'0'`, – это простейшие регулярные выражения: они просто соответствуют сами себе. Можно объединять обычные символы, так что `last` соответствует строке `'last'`. (В остальной части этого раздела мы будем записывать регулярные выражения `таким специальным стилем`, обычно без кавычек, а строки для поиска – `'в одинарных кавычках'`.)3435Некоторые символы, например `'|'` или `'('`, являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на то, как интерпретируются окружающие их регулярные выражения. Строки шаблонов регулярных выражений не могут содержать нулевые байты, но могут задавать нулевой байт с помощью нотации `\number`, например `'\x00'`.3637Специальные символы:3839**`'.'`**4041(Точка.) В режиме по умолчанию соответствует любому символу, кроме перевода строки. Если указан флаг4243[`DOTALL`](https://python-all.ru/3.1/library/re.html#re.DOTALL)4445, соответствует любому символу, включая перевод строки.4647**`'^'`**4849(Циркумфлекс.) Соответствует началу строки, а в режиме5051[`MULTILINE`](https://python-all.ru/3.1/library/re.html#re.MULTILINE)5253также соответствует позиции сразу после каждого перевода строки.5455**`'$'`**5657Соответствует концу строки или позиции перед символом новой строки в конце строки, а в режиме5859[`MULTILINE`](https://python-all.ru/3.1/library/re.html#re.MULTILINE)6061также соответствует перед переводом строки.6263`foo`6465соответствует и 'foo', и 'foobar', а регулярное выражение6667`foo$`6869соответствует только 'foo'. Ещё интереснее: поиск7071`foo.$`7273в7475`'foo1\nfoo2\n'`7677обычно находит 'foo2', но в режиме7879[`MULTILINE`](https://python-all.ru/3.1/library/re.html#re.MULTILINE)8081– 'foo1'; поиск одного8283`$`8485в8687`'foo\n'`8889найдёт два (пустых) совпадения: одно перед переводом строки, и одно в конце строки.9091**`'*'`**9293Заставляет результирующее регулярное выражение соответствовать 0 или более повторениям предшествующего выражения, захватывая максимально возможное количество повторений.9495`ab*`9697будет соответствовать 'a', 'ab' или 'a', за которым следует любое количество 'b'.9899**`'+'`**100101Заставляет результирующее регулярное выражение соответствовать 1 или более повторениям предшествующего выражения.102103`ab+`104105будет соответствовать 'a', за которым следует любое ненулевое количество 'b'; одному 'a' оно не соответствует.106107**`'?'`**108109Заставляет результирующее регулярное выражение соответствовать 0 или 1 повторению предшествующего выражения.110111`ab?`112113будет соответствовать либо 'a', либо 'ab'.114115**`*?`, `+?`, `??`**116117Квантификаторы118119`'*'`120121,122123`'+'`124125и126127`'?'`128129являются130131*жадными*132133; они захватывают максимально возможный текст. Иногда такое поведение нежелательно; если регулярное выражение134135`<.*>`136137применить к строке138139`'<H1>title</H1>'`140141, оно совпадет со всей строкой, а не только с142143`'<H1>'`144145. Добавление146147`'?'`148149после квантификатора заставляет его выполнять сопоставление в150151*нежадном*152153или154155*минимальном*156157режиме; при этом будет захвачено158159*наименьшее количество*160161символов. Используя162163`.*?`164165в предыдущем выражении, мы получим соответствие только166167`'<H1>'`168169.170171**`{m}`**172173Указывает, что должно быть сопоставлено ровно174175*m*176177копий предшествующего регулярного выражения; если совпадений меньше, всё регулярное выражение не срабатывает. Например,178179`a{6}`180181будет соответствовать ровно шести символам182183`'a'`184185, но не пяти.186187**`{m,n}`**188189Заставляет результирующее регулярное выражение соответствовать от190191*m*192193до194195*n*196197повторений предшествующего выражения, пытаясь захватить максимальное количество повторений. Например,198199`a{3,5}`200201будет соответствовать от 3 до 5 символов202203`'a'`204205. Пропуск206207*m*208209задаёт нижнюю границу, равную нулю, а пропуск210211*n*212213– бесконечную верхнюю границу. Например,214215`a{4,}b`216217будет соответствовать218219`aaaab`220221или тысяче символов222223`'a'`224225, за которыми следует226227`b`228229, но не230231`aaab`232233. Запятая не может быть опущена, иначе модификатор будет спутан с ранее описанной формой.234235**`{m,n}?`**236237Заставляет результирующее регулярное выражение соответствовать от238239*m*240241до242243*n*244245повторений предшествующего выражения, пытаясь захватить как можно246247*меньше*248249повторений. Это нежадная версия предыдущего квантификатора. Например, на 6-символьной строке250251`'aaaaaa'`252253выражение254255`a{3,5}`256257совпадет с 5 символами258259`'a'`260261, тогда как262263`a{3,5}?`264265– только с 3.266267**`'\'`**268269Либо экранирует специальные символы (позволяя сопоставлять такие символы, как `'*'`, `'?'` и т.д.), либо обозначает специальную последовательность; специальные последовательности рассматриваются ниже.270271Если вы не используете сырую строку для выражения шаблона, помните, что Python также использует обратную косую черту как escape-последовательность в строковых литералах; если escape- последовательность не распознаётся парсером Python, обратная косая черта и следующий за ней символ включаются в результирующую строку. Однако если Python распознает результирующую последовательность, обратную косую черту следует удвоить. Это сложно и трудно для понимания, поэтому настоятельно рекомендуется использовать сырые строки для всех, кроме самых простых выражений.272273**`[]`**274275Используется для указания набора символов. Символы можно перечислить по отдельности, или диапазон символов можно указать, задав два символа и разделив их символом `'-'`. Специальные символы внутри наборов не действуют. Например, `[akm$]` будет соответствовать любому из символов `'a'`, `'k'`, `'m'` или `'$'`; `[a-z]` будет соответствовать любой строчной букве, а `[a-zA-Z0-9]` – любой букве или цифре. Классы символов, такие как `\w` или `\S` (определённые ниже), также допустимы внутри диапазона, хотя соответствие символов зависит от того, активен ли режим [`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII) или [`LOCALE`](https://python-all.ru/3.1/library/re.html#re.LOCALE). Если нужно включить символ `']'` или `'-'` внутрь набора, поставьте перед ним обратную косую черту или поместите его первым символом. Шаблон `[]]` будет соответствовать `']'`, например.276277Можно сопоставлять символы, не входящие в диапазон, *дополняя* набор. Это указывается включением `'^'` в качестве первого символа набора; `'^'` в другом месте просто будет соответствовать символу `'^'`. Например, `[^5]` будет соответствовать любому символу, кроме `'5'`, а `[^^]` будет соответствовать любому символу, кроме `'^'`.278279Обратите внимание, что внутри `[]` специальные формы и специальные символы теряют свой смысл, и допустимы только описанные здесь синтаксисы. Например, `+`, `*`, `(`, `)` и так далее трактуются как литералы внутри `[]`, а обратные ссылки нельзя использовать внутри `[]`.280281**`'|'`**282283`A|B`284285, где A и B могут быть произвольными регулярными выражениями, создает регулярное выражение, которое будет соответствовать либо A, либо B. Таким способом можно разделять произвольное количество регулярных выражений с помощью286287`'|'`288289. Это можно использовать и внутри групп (см. ниже). При сканировании целевой строки выражения, разделенные290291`'|'`292293, пробуются слева направо. Когда один паттерн полностью совпадает, эта ветвь принимается. Это означает, что как только294295`A`296297совпадает,298299`B`300301больше не проверяется, даже если оно дало бы более длинное совпадение. Другими словами, оператор302303`'|'`304305никогда не бывает жадным. Чтобы сопоставить литерал306307`'|'`308309, используйте310311`\|`312313или заключите его в символьный класс, например314315`[|]`316317.318319**`(...)`**320321Соответствует любому регулярному выражению внутри скобок и обозначает начало и конец группы; содержимое группы можно получить после выполнения сопоставления, а также сопоставить позже в строке с помощью специальной последовательности322323`\number`324325, описанной ниже. Чтобы сопоставить литералы326327`'('`328329или330331`')'`332333, используйте334335`\(`336337или338339`\)`340341, или заключите их в символьный класс:342343`[(] [)]`344345.346347**`(?...)`**348349Это нотация расширения (350351`'?'`352353после354355`'('`356357в противном случае не имеет смысла). Первый символ после358359`'?'`360361определяет значение и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу;362363`(?P<name>...)`364365– единственное исключение из этого правила. Ниже перечислены поддерживаемые в настоящее время расширения.366367**`(?aiLmsux)`**368369(Одна или несколько букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`.) Группа соответствует пустой строке; буквы устанавливают соответствующие флаги: [`re.A`](https://python-all.ru/3.1/library/re.html#re.A) (только ASCII), [`re.I`](https://python-all.ru/3.1/library/re.html#re.I) (игнорировать регистр), [`re.L`](https://python-all.ru/3.1/library/re.html#re.L) (зависит от локали), [`re.M`](https://python-all.ru/3.1/library/re.html#re.M) (многострочный), [`re.S`](https://python-all.ru/3.1/library/re.html#re.S) (точка соответствует всему) и [`re.X`](https://python-all.ru/3.1/library/re.html#re.X) (подробный) для всего регулярного выражения. (Флаги описаны в разделе [*Содержание модуля*](https://python-all.ru/3.1/library/re.html#contents-of-module-re).) Это полезно, если нужно включить флаги в состав регулярного выражения, а не передавать аргумент *flag* в функцию [`re.compile()`](https://python-all.ru/3.1/library/re.html#re.compile).370371Обратите внимание, что флаг `(?x)` изменяет способ разбора выражения. Он должен быть указан первым в строке выражения или после одного или нескольких пробельных символов. Если перед флагом есть непробельные символы, результат не определён.372373**`(?:...)`**374375Незапоминающая версия обычных круглых скобок. Совпадает с любым регулярным выражением внутри скобок, но подстрока, совпавшая с группой,376377*не может*378379быть извлечена после выполнения сопоставления или использована для ссылки позже в шаблоне.380381**`(?P<name>...)`**382383Подобно обычным круглым скобкам, но подстрока, совпавшая с группой, доступна в остальной части регулярного выражения по символическому имени группы *name*. Имена групп должны быть допустимыми идентификаторами Python, и каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является нумерованной группой, как если бы группа не была именованной. Таким образом, группу с именем `id` в примере ниже также можно использовать как нумерованную группу `1`.384385Например, если шаблон – `(?P<id>[a-zA-Z_]\w*)`, то на группу можно ссылаться по имени в аргументах методов объектов сопоставления, таких как `m.group('id')` или `m.end('id')`, а также по имени в самом регулярном выражении (используя `(?P=id)`) и в тексте замены, передаваемом в `.sub()` (используя `\g<id>`).386387**`(?P=name)`**388389Совпадает с любым текстом, который совпал с ранее определённой группой с именем390391*name*392393.394395**`(?#...)`**396397Комментарий; содержимое скобок просто игнорируется.398399**`(?=...)`**400401Совпадает, если402403`...`404405совпадает далее, но не поглощает ни одного символа строки. Это называется опережающей проверкой. Например,406407`Isaac (?=Asimov)`408409совпадёт с410411`'Isaac '`412413только если за ним следует414415`'Asimov'`416417.418419**`(?!...)`**420421Совпадает, если422423`...`424425не совпадает далее. Это отрицательная опережающая проверка. Например,426427`Isaac (?!Asimov)`428429совпадёт с430431`'Isaac '`432433только если за ним434435*не*436437следует438439`'Asimov'`440441.442443**`(?<=...)`**444445Совпадение, если текущей позиции в строке предшествует совпадение с `...`, которое заканчивается на текущей позиции. Это называется *положительной ретроспективной проверкой (lookbehind)*. `(?<=abc)def` найдёт совпадение в `abcdef`, поскольку ретроспективная проверка отступит на 3 символа и проверит, соответствует ли вложенный шаблон. Вложенный шаблон должен соответствовать строкам только фиксированной длины, то есть `abc` или `a|b` допустимы, а `a*` и `a{3,4}` – нет. Обратите внимание, что шаблоны, начинающиеся с положительной ретроспективной проверки, никогда не будут совпадать в начале искомой строки; скорее всего, потребуется использовать функцию [`search()`](https://python-all.ru/3.1/library/re.html#re.search), а не [`match()`](https://python-all.ru/3.1/library/re.html#re.match).446447```python448>>> import re449>>> m = re.search('(?<=abc)def', 'abcdef')450>>> m.group(0)451'def'452```453454Этот пример ищет слово, следующее за дефисом:455456```python457>>> m = re.search('(?<=-)\w+', 'spam-egg')458>>> m.group(0)459'egg'460```461462**`(?<!...)`**463464Совпадает, если текущей позиции в строке не предшествует совпадение с465466`...`467468. Это называется469470*отрицательной ретроспективной проверкой*471472. Аналогично положительным ретроспективным проверкам, вложенный шаблон может соответствовать только строкам фиксированной длины. Шаблоны, начинающиеся с отрицательной ретроспективной проверки, могут совпадать в начале искомой строки.473474**`(?(id/name)yes-pattern|no-pattern)`**475476Пытается совпасть с477478`yes-pattern`479480, если группа с заданным481482*id*483484или485486*name*487488существует, и с489490`no-pattern`491492, если не существует.493494`no-pattern`495496необязателен и может быть опущен. Например,497498`(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)`499500– это плохой шаблон для сопоставления email, который совпадёт с501502`'<user@host.com>'`503504, а также с505506`'user@host.com'`507508, но не с509510`'<user@host.com'`511512и не с513514`'user@host.com>'`515516.517518Специальные последовательности состоят из `'\'` и символа из списка ниже. Если обычный символ отсутствует в списке, то результирующее РВ будет соответствовать второму символу. Например, `\$` соответствует символу `'$'`.519520**`\number`**521522Совпадает с содержимым группы с тем же номером. Группы нумеруются начиная с 1. Например,523524`(.+) \1`525526совпадает с527528`'the the'`529530или531532`'55 55'`533534, но не с535536`'the end'`537538(обратите внимание на пробел после группы). Эта специальная последовательность может использоваться только для сопоставления одной из первых 99 групп. Если первая цифра539540*number*541542равна 0, или543544*number*545546состоит из 3 восьмеричных цифр, она будет интерпретирована не как ссылка на группу, а как символ с восьмеричным значением547548*number*549550. Внутри551552`'['`553554и555556`']'`557558символьного класса все числовые escape-последовательности обрабатываются как символы.559560**`\A`**561562Совпадает только в начале строки.563564**`\b`**565566Соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность буквенно-цифровых символов Unicode или символа подчёркивания, поэтому конец слова обозначается пробелом или не буквенно-цифровым символом Unicode, не являющимся подчёркиванием. Обратите внимание, что формально567568`\b`569570определяется как граница между символом571572`\w`573574и символом575576`\W`577578(или наоборот). По умолчанию используются буквенно-цифровые символы Unicode, но это можно изменить с помощью флага579580[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)581582. Внутри диапазона символов583584`\b`585586представляет символ backspace для совместимости со строковыми литералами Python.587588**`\B`**589590Соответствует пустой строке, но только когда она591592*не*593594находится в начале или конце слова. Это противоположность595596`\b`597598, поэтому символами слова являются буквенно-цифровые символы Unicode или подчёркивание, хотя это можно изменить, используя флаг599600[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)601602.603604**`\d`**605606**Для шаблонов Unicode (str):**607608Соответствует любой цифре Unicode (включая609610`[0-9]`611612, а также многие другие цифровые символы). Если используется флаг613614[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)615616, сопоставляется только617618`[0-9]`619620(но флаг влияет на всё регулярное выражение, поэтому в таких случаях использование явного621622`[0-9]`623624может быть лучшим выбором).625626**Для 8-битных (байтовых) шаблонов:**627628Соответствует любой десятичной цифре; это эквивалентно629630`[0-9]`631632.633634**`\D`**635636Совпадает с любым символом, не являющимся десятичной цифрой Unicode. Это противоположность637638`\d`639640. Если используется флаг641642[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)643644, это становится эквивалентом645646`[^0-9]`647648(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явное649650`[^0-9]`651652).653654**`\s`**655656**Для шаблонов Unicode (str):**657658Совпадает с пробельными символами Unicode (к которым относятся659660`[ \t\n\r\f\v]`661662, а также многие другие символы, например неразрывные пробелы, требуемые правилами типографики во многих языках). Если используется флаг663664[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)665666, совпадает только667668`[ \t\n\r\f\v]`669670(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явное671672`[ \t\n\r\f\v]`673674).675676**Для 8-битных (байтовых) шаблонов:**677678Совпадает с символами, считающимися пробельными в наборе символов ASCII; это эквивалентно679680`[ \t\n\r\f\v]`681682.683684**`\S`**685686Совпадает с любым символом, не являющимся пробельным символом Unicode. Это противоположность687688`\s`689690. Если используется флаг691692[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)693694, это становится эквивалентом695696`[^ \t\n\r\f\v]`697698(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явное699700`[^ \t\n\r\f\v]`701702).703704**`\w`**705706**Для шаблонов Unicode (str):**707708Совпадает с символами слова Unicode; сюда входят большинство символов, которые могут быть частью слова в любом языке, а также цифры и символ подчёркивания. Если используется флаг709710[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)711712, совпадает только713714`[a-zA-Z0-9_]`715716(но флаг влияет на всё регулярное выражение, поэтому в таких случаях лучше использовать явное717718`[a-zA-Z0-9_]`719720).721722**Для 8-битных (байтовых) шаблонов:**723724Совпадает с символами, считающимися буквенно-цифровыми в наборе символов ASCII; это эквивалентно725726`[a-zA-Z0-9_]`727728.729730**`\W`**731732Соответствует любому символу, который не является символом слова Unicode. Это противоположность733734`\w`735736. Если используется флаг737738[`ASCII`](https://python-all.ru/3.1/library/re.html#re.ASCII)739740, это становится эквивалентом741742`[^a-zA-Z0-9_]`743744(но флаг влияет на всё регулярное выражение, поэтому в таких случаях использование явного745746`[^a-zA-Z0-9_]`747748может быть лучшим выбором).749750**`\Z`**751752Совпадение только в конце строки.753754Большинство стандартных управляющих последовательностей, поддерживаемых строковыми литералами Python, также принимаются синтаксическим анализатором регулярных выражений:755756```python757\a \b \f \n758\r \t \v \x759\\760```761762Восьмеричные escape-последовательности поддерживаются в ограниченной форме: если первая цифра – 0, или если присутствуют три восьмеричные цифры, это считается восьмеричной escape-последовательностью. В противном случае это ссылка на группу. Как и в строковых литералах, восьмеричные escape-последовательности всегда имеют длину не более трёх цифр.763764## 7.2.2. Сопоставление и поиск765766Python предлагает две различные примитивные операции на основе регулярных выражений: **match** проверяет совпадение только в начале строки, тогда как **search** проверяет совпадение в любом месте строки (именно так по умолчанию работает Perl).767768Обратите внимание, что match может отличаться от search, даже если используется регулярное выражение, начинающееся с `'^'`: `'^'` совпадает только в начале строки или в режиме [`MULTILINE`](https://python-all.ru/3.1/library/re.html#re.MULTILINE) также сразу после перевода строки. Операция match успешна, только если шаблон совпадает в начале строки (независимо от режима) или в начальной позиции, заданной необязательным аргументом *pos*, независимо от того, предшествует ли ей перевод строки.769770```python771>>> re.match("c", "abcdef") # Нет совпадения.772>>> re.search("c", "abcdef") # Совпадает.773<_sre.SRE_Match object at ...>774```775776## 7.2.3. Содержимое модуля777778Модуль определяет несколько функций, констант и одно исключение. Некоторые из функций являются упрощёнными версиями полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используется скомпилированная форма.779780#### `re.compile(pattern[, flags])`781782Компилирует шаблон регулярного выражения в объект регулярного выражения, который можно использовать для поиска совпадений с помощью его методов [`match()`](https://python-all.ru/3.1/library/re.html#re.match) и [`search()`](https://python-all.ru/3.1/library/re.html#re.search), описанных ниже.783784Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые из следующих переменных, комбинируя их с помощью побитового ИЛИ (оператор `|`).785786Последовательность787788```python789prog = re.compile(pattern)790result = prog.match(string)791```792793эквивалентна794795```python796result = re.match(pattern, string)797```798799но использование [`re.compile()`](https://python-all.ru/3.1/library/re.html#re.compile) и сохранение полученного объекта регулярного выражения для повторного использования более эффективно, когда выражение будет использоваться несколько раз в одной программе.800801> **Примечание**802>803> Скомпилированные версии последних шаблонов, переданных в [`re.match()`](https://python-all.ru/3.1/library/re.html#re.match), [`re.search()`](https://python-all.ru/3.1/library/re.html#re.search) или [`re.compile()`](https://python-all.ru/3.1/library/re.html#re.compile), кэшируются, поэтому программам, использующим лишь несколько регулярных выражений за раз, не нужно беспокоиться о компиляции регулярных выражений.804805#### `re.A`806807#### `re.ASCII`808809Заставляет `\w`, `\W`, `\b`, `\B`, `\d`, `\D`, `\s` и `\S` выполнять сопоставление только из ASCII вместо полного сопоставления Unicode. Это имеет смысл только для шаблонов Unicode и игнорируется для байтовых шаблонов.810811Обратите внимание, что для обратной совместимости флаг `re.U` всё ещё существует (как и его синоним `re.UNICODE` и его встроенный аналог `(?u)`), но они избыточны в Python 3, так как сопоставление по умолчанию для строк выполняется с Unicode (а сопоставление Unicode не допускается для байтов).812813#### `re.I`814815#### `re.IGNORECASE`816817Выполняет сопоставление без учёта регистра; выражения вроде818819`[A-Z]`820821будут соответствовать также и строчным буквам. На это не влияет текущая локаль, и оно работает с символами Unicode так, как и ожидается.822823#### `re.L`824825#### `re.LOCALE`826827Заставляет828829`\w`830831,832833`\W`834835,836837`\b`838839,840841`\B`842843,844845`\s`846847и848849`\S`850851зависеть от текущей локали. Использование этого флага не рекомендуется, так как механизм локали очень ненадёжен и в любом случае обрабатывает только одну «культуру» за раз; вместо этого следует использовать сопоставление Unicode, которое является стандартным в Python 3 для шаблонов Unicode (str).852853#### `re.M`854855#### `re.MULTILINE`856857При указании этого флага символ шаблона858859`'^'`860861совпадает с началом строки и с началом каждой строки (сразу после каждого перевода строки); а символ шаблона862863`'$'`864865совпадает с концом строки и с концом каждой строки (непосредственно перед каждым переводом строки). По умолчанию866867`'^'`868869совпадает только с началом строки, а870871`'$'`872873– только с концом строки и непосредственно перед переводом строки (если он есть) в конце строки.874875#### `re.S`876877#### `re.DOTALL`878879Заставляет специальный символ880881`'.'`882883совпадать с любым символом, включая перевод строки; без этого флага884885`'.'`886887будет совпадать с любым символом,888889*кроме*890891перевода строки.892893#### `re.X`894895#### `re.VERBOSE`896897Этот флаг позволяет писать более читаемые регулярные выражения. Пробельные символы в шаблоне игнорируются, кроме случаев, когда они находятся внутри символьного класса или перед ними стоит неэкранированная обратная косая черта. Кроме того, если строка содержит `'#'`, не находящийся в символьном классе и не предварённый неэкранированной обратной косой чертой, все символы от самого левого такого `'#'` до конца строки игнорируются.898899Это означает, что следующие два объекта регулярных выражений, которые соответствуют десятичному числу, функционально эквивалентны:900901```python902a = re.compile(r"""\d + # the integral part903 \. # the decimal point904 \d * # some fractional digits""", re.X)905b = re.compile(r"\d+\.\d*")906```907908#### `re.search(pattern, string[, flags])`909910Просматривает911912*string*913914в поиске места, где регулярное выражение915916*pattern*917918даёт совпадение, и возвращает соответствующий экземпляр919920[`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject)921922. Возвращает923924`None`925926, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от нахождения совпадения нулевой длины в какой-то точке строки.927928#### `re.match(pattern, string[, flags])`929930Если ноль или более символов в начале *string* соответствуют регулярному выражению *pattern*, возвращает соответствующий экземпляр [`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.931932> **Примечание**933>934> Если нужно найти совпадение в любом месте *string*, используйте [`search()`](https://python-all.ru/3.1/library/re.html#re.search) вместо этого.935936#### `re.split(pattern, string[, maxsplit=0, flags=0])`937938Разделяет *string* по вхождениям *pattern*. Если в *pattern* используются захватывающие круглые скобки, то текст всех групп в шаблоне также возвращается как часть результирующего списка. Если *maxsplit* не равно нулю, то происходит не более *maxsplit* разбиений, а остаток строки возвращается как последний элемент списка.939940```python941>>> re.split('\W+', 'Words, words, words.')942['Words', 'words', 'words', '']943>>> re.split('(\W+)', 'Words, words, words.')944['Words', ', ', 'words', ', ', 'words', '.', '']945>>> re.split('\W+', 'Words, words, words.', 1)946['Words', 'words, words.']947>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)948['0', '3', '9']949```950951Если в разделителе есть захватывающие группы и он совпадает в начале строки, результат будет начинаться с пустой строки. То же самое относится и к концу строки:952953```python954>>> re.split('(\W+)', '...words, words...')955['', '...', 'words', ', ', 'words', '...', '']956```957958Таким образом, компоненты разделителя всегда находятся на одних и тех же относительных позициях в результирующем списке (например, если в разделителе есть одна захватывающая группа, то на 0-м, 2-м и так далее).959960Обратите внимание, что *split* никогда не разделяет строку по пустому совпадению шаблона. Например:961962```python963>>> re.split('x*', 'foo')964['foo']965>>> re.split("(?m)^$", "foo\n\nbar\n")966['foo\n\nbar\n']967```968969Изменено в версии 3.1: Добавлен необязательный аргумент flags.970971#### `re.findall(pattern, string[, flags])`972973Возвращает все непересекающиеся совпадения974975*pattern*976977в978979*string*980981, в виде списка строк. Строка982983*string*984985сканируется слева направо, совпадения возвращаются в порядке обнаружения. Если в шаблоне присутствуют одна или несколько групп, возвращается список групп; если групп больше одной – список кортежей. Пустые совпадения включаются в результат, кроме случаев, когда они примыкают к началу другого совпадения.986987#### `re.finditer(pattern, string[, flags])`988989Возвращает990991[*итератор*](https://python-all.ru/3.1/glossary.html#term-iterator)992993, выдающий экземпляры994995[`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject)996997для всех непересекающихся совпадений регулярного выражения998999*pattern*10001001в10021003*string*10041005. Строка10061007*string*10081009просматривается слева направо, и совпадения возвращаются в порядке обнаружения. Пустые совпадения включаются в результат, если они не касаются начала другого совпадения.10101011#### `re.sub(pattern, repl, string[, count, flags])`10121013Возвращает строку, полученную заменой крайних левых непересекающихся вхождений *pattern* в *string* на замену *repl*. Если шаблон не найден, *string* возвращается без изменений. *repl* может быть строкой или функцией; если это строка, все управляющие последовательности в ней обрабатываются. То есть `\n` преобразуется в символ новой строки, `\r` преобразуется в символ возврата каретки и так далее. Неизвестные управляющие последовательности, такие как `\j`, остаются без изменений. Обратные ссылки, такие как `\6`, заменяются подстрокой, совпавшей с группой 6 в шаблоне. Например:10141015```python1016>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',1017... r'static PyObject*\npy_\1(void)\n{',1018... 'def myfunc():')1019'static PyObject*\npy_myfunc(void)\n{'1020```10211022Если *repl* – функция, она вызывается для каждого непересекающегося вхождения *pattern*. Функция принимает один аргумент – объект совпадения – и возвращает строку замены. Например:10231024```python1025>>> def dashrepl(matchobj):1026... if matchobj.group(0) == '-': return ' '1027... else: return '-'1028>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')1029'pro--gram files'1030>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)1031'Baked Beans & Spam'1032```10331034Шаблон может быть строкой или объектом RE.10351036Необязательный аргумент *count* – это максимальное количество заменяемых вхождений шаблона; *count* должен быть неотрицательным целым числом. Если опущено или равно нулю, заменяются все вхождения. Пустые совпадения шаблона заменяются только тогда, когда они не примыкают к предыдущему совпадению, поэтому `sub('x*', '-', 'abc')` возвращает `'-a-b-c-'`.10371038В дополнение к экранированию символов и обратным ссылкам, описанным выше, `\g<name>` будет использовать подстроку, совпавшую с группой с именем `name`, как определено синтаксисом `(?P<name>...)`. `\g<number>` использует соответствующий номер группы; `\g<2>` поэтому эквивалентно `\2`, но не является неоднозначным в замене, такой как `\g<2>0`. `\20` было бы интерпретировано как ссылка на группу 20, а не ссылка на группу 2, за которой следует литерал `'0'`. Обратная ссылка `\g<0>` подставляет всю подстроку, совпавшую с регулярным выражением.10391040Изменено в версии 3.1: Добавлен необязательный аргумент flags.10411042#### `re.subn(pattern, repl, string[, count, flags])`10431044Выполняет ту же операцию, что и [`sub()`](https://python-all.ru/3.1/library/re.html#re.sub), но возвращает кортеж `(new_string, number_of_subs_made)`.10451046Изменено в версии 3.1: Добавлен необязательный аргумент flags.10471048#### `re.escape(string)`10491050Возвращает10511052*string*10531054, в котором все небуквенно-цифровые символы экранированы обратной косой чертой; это полезно, если требуется найти произвольную литеральную строку, которая может содержать метасимволы регулярных выражений.10551056#### `re.purge()`10571058Очищает кэш регулярных выражений.10591060#### `exception re.error`10611062Исключение возникает, когда строка, переданная одной из функций здесь, не является допустимым регулярным выражением (например, может содержать непарные скобки) или когда происходит другая ошибка во время компиляции или сопоставления. Это никогда не является ошибкой, если строка не содержит совпадений с шаблоном.10631064## 7.2.4. Объекты регулярных выражений10651066#### `class re.RegexObject`10671068Класс [`RegexObject`](https://python-all.ru/3.1/library/re.html#re.RegexObject) поддерживает следующие методы и атрибуты:10691070#### `search(string[, pos[, endpos]])`10711072Просматривает строку *string* в поисках места, где это регулярное выражение даёт совпадение, и возвращает соответствующий экземпляр [`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject). Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в какой-либо точке строки.10731074Необязательный второй параметр *pos* задаёт индекс в строке, с которого начинается поиск; по умолчанию `0`. Это не полностью эквивалентно срезу строки; символ шаблона `'^'` сопоставляется с реальным началом строки и с позициями сразу после символа новой строки, но не обязательно с индексом, с которого должен начинаться поиск.10751076Необязательный параметр *endpos* ограничивает глубину поиска в строке; строка считается длиной в *endpos* символов, поэтому на совпадение проверяются только символы от *pos* до `endpos - 1`. Если *endpos* меньше *pos*, совпадение не будет найдено; в противном случае, если *rx* – скомпилированный объект регулярного выражения, `rx.search(string, 0, 50)` эквивалентно `rx.search(string[:50], 0)`.10771078```python1079>>> pattern = re.compile("d")1080>>> pattern.search("dog") # Совпадение на индексе 01081<_sre.SRE_Match object at ...>1082>>> pattern.search("dog", 1) # Совпадения нет; поиск не включает "d"1083```10841085#### `match(string[, pos[, endpos]])`10861087Если ноль или более символов в *начале* *string* соответствуют этому регулярному выражению, возвращается соответствующий экземпляр [`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject). Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.10881089Необязательные параметры *pos* и *endpos* имеют тот же смысл, что и для метода [`search()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.search).10901091> **Примечание**1092>1093> Если требуется найти совпадение в любом месте строки *string*, используйте [`search()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.search).10941095```python1096>>> pattern = re.compile("o")1097>>> pattern.match("dog") # Совпадения нет, так как "o" не в начале строки "dog".1098>>> pattern.match("dog", 1) # Совпадение есть, так как "o" – второй символ строки "dog".1099<_sre.SRE_Match object at ...>1100```11011102#### `split(string[, maxsplit=0])`11031104Идентично функции11051106[`split()`](https://python-all.ru/3.1/library/re.html#re.split)11071108, используя скомпилированный шаблон.11091110#### `findall(string[, pos[, endpos]])`11111112Аналогично функции11131114[`findall()`](https://python-all.ru/3.1/library/re.html#re.findall)11151116, использующей скомпилированный шаблон, но также принимает необязательные параметры11171118*pos*11191120и11211122*endpos*11231124, ограничивающие область поиска, как в11251126[`match()`](https://python-all.ru/3.1/library/re.html#re.match)11271128.11291130#### `finditer(string[, pos[, endpos]])`11311132Аналогично функции11331134[`finditer()`](https://python-all.ru/3.1/library/re.html#re.finditer)11351136, использующей скомпилированный шаблон, но также принимает необязательные параметры11371138*pos*11391140и11411142*endpos*11431144, ограничивающие область поиска, как в11451146[`match()`](https://python-all.ru/3.1/library/re.html#re.match)11471148.11491150#### `sub(repl, string[, count=0])`11511152Идентична функции11531154[`sub()`](https://python-all.ru/3.1/library/re.html#re.sub)11551156, использующей скомпилированный шаблон.11571158#### `subn(repl, string[, count=0])`11591160Идентична функции11611162[`subn()`](https://python-all.ru/3.1/library/re.html#re.subn)11631164, использующей скомпилированный шаблон.11651166#### `flags`11671168Аргумент flags, использованный при компиляции объекта RE, или11691170`0`11711172, если флаги не были указаны.11731174#### `groups`11751176Количество захватываемых групп в шаблоне.11771178#### `groupindex`11791180Словарь, сопоставляющий любые символьные имена групп, определённые с помощью11811182`(?P<id>)`11831184, с номерами групп. Словарь пуст, если в шаблоне не использовались символьные группы.11851186#### `pattern`11871188Строка шаблона, из которой был скомпилирован объект RE.11891190## 7.2.5. Объекты Match11911192#### `class re.MatchObject`11931194Объекты Match всегда имеют булево значение [`True`](https://python-all.ru/3.1/library/constants.html#True), поэтому можно проверить, например, дал ли [`match()`](https://python-all.ru/3.1/library/re.html#re.match) совпадение с помощью простого оператора if. Они поддерживают следующие методы и атрибуты:11951196#### `expand(template)`11971198Возвращает строку, полученную путём подстановки обратной косой черты в строку шаблона11991200*template*12011202, как это делает метод12031204[`sub()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.sub)12051206. Управляющие последовательности такие как12071208`\n`12091210преобразуются в соответствующие символы, а числовые обратные ссылки (12111212`\1`12131214,12151216`\2`12171218) и именованные обратные ссылки (12191220`\g<1>`12211222,12231224`\g<name>`12251226) заменяются содержимым соответствующей группы.12271228#### `group([group1, ...])`12291230Возвращает одну или несколько подгрупп совпадения. Если аргумент один, результатом является одна строка; если аргументов несколько, результат – кортеж с одним элементом на каждый аргумент. Без аргументов *group1* по умолчанию равен нулю (возвращается всё совпадение). Если аргумент *groupN* равен нулю, соответствующее возвращаемое значение – вся сопоставленная строка; если он находится в диапазоне \[1..99\] включительно, это строка, соответствующая соответствующей группе в скобках. Если номер группы отрицателен или больше количества групп, определённых в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.1/library/exceptions.html#IndexError). Если группа содержится в части шаблона, которая не совпала, соответствующий результат равен `None`. Если группа содержится в части шаблона, которая совпала несколько раз, возвращается последнее совпадение.12311232```python1233>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")1234>>> m.group(0) # Всё совпадение1235'Isaac Newton'1236>>> m.group(1) # Первая группа в скобках.1237'Isaac'1238>>> m.group(2) # Вторая группа в скобках.1239'Newton'1240>>> m.group(1, 2) # Несколько аргументов дают кортеж.1241('Isaac', 'Newton')1242```12431244Если в регулярном выражении используется синтаксис `(?P<name>...)`, то аргументы *groupN* могут также быть строками, идентифицирующими группы по их имени. Если строковый аргумент не используется как имя группы в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.1/library/exceptions.html#IndexError).12451246Довольно сложный пример:12471248```python1249>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")1250>>> m.group('first_name')1251'Malcolm'1252>>> m.group('last_name')1253'Reynolds'1254```12551256Именованные группы также можно указывать по их индексу:12571258```python1259>>> m.group(1)1260'Malcolm'1261>>> m.group(2)1262'Reynolds'1263```12641265Если группа совпадает несколько раз, доступно только последнее совпадение:12661267```python1268>>> m = re.match(r"(..)+", "a1b2c3") # Совпадает 3 раза.1269>>> m.group(1) # Возвращает только последнее совпадение.1270'c3'1271```12721273#### `groups([default])`12741275Возвращает кортеж, содержащий все подгруппы совпадения, от 1 до количества групп в шаблоне. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`.12761277Например:12781279```python1280>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")1281>>> m.groups()1282('24', '1632')1283```12841285Если сделать десятичную точку и всё после неё необязательными, не все группы могут участвовать в совпадении. Эти группы по умолчанию будут равны `None`, если не указан аргумент *default*:12861287```python1288>>> m = re.match(r"(\d+)\.?(\d+)?", "24")1289>>> m.groups() # Вторая группа по умолчанию – None.1290('24', None)1291>>> m.groups('0') # Теперь вторая группа по умолчанию – '0'.1292('24', '0')1293```12941295#### `groupdict([default])`12961297Возвращает словарь, содержащий все *именованные* подгруппы совпадения, где ключом является имя подгруппы. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`. Например:12981299```python1300>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")1301>>> m.groupdict()1302{'first_name': 'Malcolm', 'last_name': 'Reynolds'}1303```13041305#### `start([group])`13061307#### `end([group])`13081309Возвращает индексы начала и конца подстроки, сопоставленной с *group*; *group* по умолчанию равен нулю (означает всю сопоставленную подстроку). Возвращает `-1`, если *group* существует, но не участвовал в совпадении. Для объекта совпадения *m* и группы *g*, которая участвовала в совпадении, подстрока, сопоставленная группой *g* (эквивалент `m.group(g)`), – это13101311```python1312m.string[m.start(g):m.end(g)]1313```13141315Обратите внимание, что `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.1/library/exceptions.html#IndexError).13161317Пример, который удалит *remove\_this* из адресов электронной почты:13181319```python1320>>> email = "tony@tiremove_thisger.net"1321>>> m = re.search("remove_this", email)1322>>> email[:m.start()] + email[m.end():]1323'tony@tiger.net'1324```13251326#### `span([group])`13271328Для13291330[`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject)13311332*m*13331334возвращает кортеж из двух элементов13351336`(m.start(group), m.end(group))`13371338. Обратите внимание, что если13391340*group*13411342не участвовала в совпадении, возвращается13431344`(-1, -1)`13451346. Значение13471348*group*13491350по умолчанию равно нулю, то есть всё совпадение.13511352#### `pos`13531354Значение13551356*pos*13571358, переданное методу13591360[`search()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.search)13611362или13631364[`match()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.match)13651366объекта13671368[`RegexObject`](https://python-all.ru/3.1/library/re.html#re.RegexObject)13691370. Это индекс в строке, с которого движок RE начал поиск совпадения.13711372#### `endpos`13731374Значение13751376*endpos*13771378, переданное методу13791380[`search()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.search)13811382или13831384[`match()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.match)13851386объекта13871388[`RegexObject`](https://python-all.ru/3.1/library/re.html#re.RegexObject)13891390. Это индекс в строке, за который движок регулярных выражений не выходит.13911392#### `lastindex`13931394Целочисленный индекс последней совпавшей захватывающей группы или13951396`None`13971398, если ни одна группа не совпала. Например, выражения13991400`(a)b`14011402,14031404`((a)(b))`14051406и14071408`((ab))`14091410будут иметь14111412`lastindex == 1`14131414, если применить к строке14151416`'ab'`14171418, а выражение14191420`(a)(b)`14211422будет иметь14231424`lastindex == 2`14251426, если применить к той же строке.14271428#### `lastgroup`14291430Имя последней совпавшей захватывающей группы или14311432`None`14331434, если у группы не было имени или если ни одна группа не совпала.14351436#### `re`14371438Объект регулярного выражения, чей метод14391440[`match()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.match)14411442или14431444[`search()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.search)14451446создал этот экземпляр14471448[`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject)14491450.14511452#### `string`14531454Строка, переданная в14551456[`match()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.match)14571458или14591460[`search()`](https://python-all.ru/3.1/library/re.html#re.RegexObject.search)14611462.14631464## 7.2.6. Примеры14651466### 7.2.6.1. Проверка на пару14671468В этом примере используется следующая вспомогательная функция для более наглядного отображения объектов совпадения:14691470```python1471def displaymatch(match):1472 if match is None:1473 return None1474 return '<Match: %r, groups=%r>' % (match.group(), match.groups())1475```14761477Предположим, вы пишете программу для покера, где рука игрока представлена в виде строки из 5 символов, каждый символ обозначает карту: «a» – туз, «k» – король, «q» – дама, j – валет, «0» – десятка, а «1»–«9» – карты с соответствующим номиналом.14781479Чтобы проверить, является ли заданная строка допустимой рукой, можно поступить следующим образом:14801481```python1482>>> valid = re.compile(r"[0-9akqj]{5}$")1483>>> displaymatch(valid.match("ak05q")) # Допустимо.1484"<Match: 'ak05q', groups=()>"1485>>> displaymatch(valid.match("ak05e")) # Недопустимо.1486>>> displaymatch(valid.match("ak0")) # Недопустимо.1487>>> displaymatch(valid.match("727ak")) # Допустимо.1488"<Match: '727ak', groups=()>"1489```14901491Та последняя рука, `"727ak"`, содержала пару, то есть две карты одного достоинства. Чтобы сопоставить это с помощью регулярного выражения, можно использовать обратные ссылки следующим образом:14921493```python1494>>> pair = re.compile(r".*(.).*\1")1495>>> displaymatch(pair.match("717ak")) # Пара семёрок.1496"<Match: '717', groups=('7',)>"1497>>> displaymatch(pair.match("718ak")) # Нет пар.1498>>> displaymatch(pair.match("354aa")) # Пара тузов.1499"<Match: '354aa', groups=('a',)>"1500```15011502Чтобы узнать, какая карта образует пару, можно использовать метод [`group()`](https://python-all.ru/3.1/library/re.html#re.MatchObject.group) объекта [`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject) следующим образом:15031504```python1505>>> pair.match("717ak").group(1)1506'7'15071508# Error because re.match() returns None, which doesn't have a group() method:1509>>> pair.match("718ak").group(1)1510Traceback (most recent call last):1511 File "<pyshell#23>", line 1, in <module>1512 re.match(r".*(.).*\1", "718ak").group(1)1513AttributeError: 'NoneType' object has no attribute 'group'15141515>>> pair.match("354aa").group(1)1516'a'1517```15181519### 7.2.6.2. Имитация scanf()15201521В Python пока нет аналога `scanf()`. Регулярные выражения в целом мощнее, хотя и более многословны, чем строки форматирования `scanf()`. В таблице ниже приведены более или менее эквивалентные соответствия между токенами формата `scanf()` и регулярными выражениями.15221523| `scanf()` Токен | Регулярное выражение |1524| --- | --- |1525| `%c` | `.` |1526| `%5c` | `.{5}` |1527| `%d` | `[-+]?\d+` |1528| `%e`, `%E`, `%f`, `%g` | `[-+]?(\d+(\.\d*)?\|\.\d+)([eE][-+]?\d+)?` |1529| `%i` | `[-+]?(0[xX][\dA-Fa-f]+\|0[0-7]*\|\d+)` |1530| `%o` | `0[0-7]*` |1531| `%s` | `\S+` |1532| `%u` | `\d+` |1533| `%x`, `%X` | `0[xX][\dA-Fa-f]+` |15341535Чтобы извлечь имя файла и числа из строки вида15361537```python1538/usr/sbin/sendmail - 0 errors, 4 warnings1539```15401541Можно использовать формат `scanf()`, например15421543```python1544%s - %d errors, %d warnings1545```15461547Эквивалентное регулярное выражение будет15481549```python1550(\S+) - (\d+) errors, (\d+) warnings1551```15521553### 7.2.6.3. Избегание рекурсии15541555Если вы создаёте регулярные выражения, требующие от движка выполнения большого объёма рекурсии, может возникнуть исключение [`RuntimeError`](https://python-all.ru/3.1/library/exceptions.html#RuntimeError) с сообщением `maximum recursion limit` exceeded. Например,15561557```python1558>>> s = 'Begin ' + 1000*'a very long string ' + 'end'1559>>> re.match('Begin (\w| )*? end', s).end()1560Traceback (most recent call last):1561 File "<stdin>", line 1, in ?1562 File "/usr/local/lib/python3.1/re.py", line 132, in match1563 return _compile(pattern, flags).match(string)1564RuntimeError: maximum recursion limit exceeded1565```15661567Часто можно перестроить регулярное выражение, чтобы избежать рекурсии.15681569Простые случаи использования шаблона `*?` обрабатываются особым образом, чтобы избежать рекурсии. Таким образом, указанное выше регулярное выражение может избежать рекурсии, если его переписать как `Begin [a-zA-Z0-9_ ]*?end`. В качестве дополнительного преимущества такие регулярные выражения будут работать быстрее, чем их рекурсивные аналоги.15701571### 7.2.6.4. search() и match()15721573В двух словах, [`match()`](https://python-all.ru/3.1/library/re.html#re.match) пытается сопоставить шаблон только в начале строки, тогда как [`search()`](https://python-all.ru/3.1/library/re.html#re.search) находит шаблон в любом месте строки. Например:15741575```python1576>>> re.match("o", "dog") # Совпадение отсутствует, так как «o» не является первой буквой слова «dog».1577>>> re.search("o", "dog") # Совпадение найдено, так как search() ищет по всей строке.1578<_sre.SRE_Match object at ...>1579```15801581> **Примечание**1582>1583> Следующее относится только к объектам регулярных выражений, созданным с помощью `re.compile("pattern")`, а не к примитивам `re.match(pattern, string)` или `re.search(pattern, string)`.15841585У [`match()`](https://python-all.ru/3.1/library/re.html#re.match) есть необязательный второй параметр, который задаёт индекс в строке, с которого должен начинаться поиск:15861587```python1588>>> pattern = re.compile("o")1589>>> pattern.match("dog") # Нет совпадения, так как "o" не находится в начале строки "dog."15901591# Equivalent to the above expression as 0 is the default starting index:1592>>> pattern.match("dog", 0)15931594# Match as "o" is the 2nd character of "dog" (index 0 is the first):1595>>> pattern.match("dog", 1)1596<_sre.SRE_Match object at ...>1597>>> pattern.match("dog", 2) # Нет совпадения, так как "o" не является третьим символом строки "dog."1598```15991600### 7.2.6.5. Создание телефонной книги16011602[`split()`](https://python-all.ru/3.1/library/re.html#re.split) разбивает строку на список, используя переданный шаблон в качестве разделителя. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые Python может легко читать и изменять, как показано в следующем примере, создающем телефонный справочник.16031604Сначала – входные данные. Обычно они берутся из файла, здесь мы используем синтаксис тройных кавычек:16051606```python1607>>> input = """Ross McFluff: 834.345.1254 155 Elm Street1608...1609... Ronald Heathmore: 892.345.3428 436 Finley Avenue1610... Frank Burger: 925.541.7625 662 South Dogwood Way1611...1612...1613... Heather Albrecht: 548.326.4584 919 Park Place"""1614```16151616Записи разделяются одним или несколькими символами новой строки. Теперь преобразуем строку в список, где каждая непустая строка будет отдельной записью:16171618```python1619>>> entries = re.split("\n+", input)1620>>> entries1621['Ross McFluff: 834.345.1254 155 Elm Street',1622'Ronald Heathmore: 892.345.3428 436 Finley Avenue',1623'Frank Burger: 925.541.7625 662 South Dogwood Way',1624'Heather Albrecht: 548.326.4584 919 Park Place']1625```16261627Наконец, каждая запись разбивается на список, содержащий имя, фамилию, номер телефона и адрес. Используется параметр `maxsplit` функции [`split()`](https://python-all.ru/3.1/library/re.html#re.split), потому что адрес содержит пробелы – наш разделитель:16281629```python1630>>> [re.split(":? ", entry, 3) for entry in entries]1631[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],1632['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],1633['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],1634['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]1635```16361637Шаблон `:?` соответствует двоеточию после фамилии, поэтому оно не попадает в результирующий список. С помощью `maxsplit`, равного `4`, можно отделить номер дома от названия улицы:16381639```python1640>>> [re.split(":? ", entry, 4) for entry in entries]1641[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],1642['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],1643['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],1644['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]1645```16461647### 7.2.6.6. Преобразование текста16481649[`sub()`](https://python-all.ru/3.1/library/re.html#re.sub) заменяет каждое вхождение шаблона на строку или результат функции. В этом примере показано использование [`sub()`](https://python-all.ru/3.1/library/re.html#re.sub) с функцией для «изменения» (munge) текста, то есть перемешивания порядка всех символов в каждом слове предложения, кроме первого и последнего:16501651```python1652>>> def repl(m):1653... inner_word = list(m.group(2))1654... random.shuffle(inner_word)1655... return m.group(1) + "".join(inner_word) + m.group(3)1656>>> text = "Professor Abdolmalek, please report your absences promptly."1657>>> re.sub(r"(\w)(\w+)(\w)", repl, text)1658'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'1659>>> re.sub(r"(\w)(\w+)(\w)", repl, text)1660'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'1661```16621663### 7.2.6.7. Поиск всех наречий16641665[`findall()`](https://python-all.ru/3.1/library/re.html#re.findall) находит *все* вхождения шаблона, а не только первое, как [`search()`](https://python-all.ru/3.1/library/re.html#re.search). Например, если бы писателю потребовалось найти все наречия в тексте, он или она могли бы использовать [`findall()`](https://python-all.ru/3.1/library/re.html#re.findall) следующим образом:16661667```python1668>>> text = "He was carefully disguised but captured quickly by police."1669>>> re.findall(r"\w+ly", text)1670['carefully', 'quickly']1671```16721673### 7.2.6.8. Поиск всех наречий и их позиций16741675Если требуется больше информации о всех совпадениях с шаблоном, чем просто совпавший текст, то полезен [`finditer()`](https://python-all.ru/3.1/library/re.html#re.finditer), поскольку он возвращает экземпляры [`MatchObject`](https://python-all.ru/3.1/library/re.html#re.MatchObject), а не строки. Продолжая предыдущий пример, если бы писатель захотел найти все наречия *и их позиции* в некотором тексте, он бы использовал [`finditer()`](https://python-all.ru/3.1/library/re.html#re.finditer) следующим образом:16761677```python1678>>> text = "He was carefully disguised but captured quickly by police."1679>>> for m in re.finditer(r"\w+ly", text):1680... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))168107-16: carefully168240-47: quickly1683```16841685### 7.2.6.9. Обозначение сырых строк16861687Сырые строки (`r"text"`) делают регулярные выражения читаемыми. Без них каждый обратный слеш (`'\'`) в регулярном выражении пришлось бы экранировать дополнительным слешем. Например, следующие две строки кода функционально идентичны:16881689```python1690>>> re.match(r"\W(.)\1\W", " ff ")1691<_sre.SRE_Match object at ...>1692>>> re.match("\\W(.)\\1\\W", " ff ")1693<_sre.SRE_Match object at ...>1694```16951696Если требуется сопоставить литеральный обратный слеш, его необходимо экранировать в регулярном выражении. В сырых строках это означает `r"\\"`. Без сырых строк придётся использовать `"\\\\"`, поэтому следующие строки кода функционально идентичны:16971698```python1699>>> re.match(r"\\", r"\\")1700<_sre.SRE_Match object at ...>1701>>> re.match("\\\\", r"\\")1702<_sre.SRE_Match object at ...>1703```1704