re.md
1> **Источник:** https://python-all.ru/3.0/library/re.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `re` – Операции с регулярными выражениями89Этот модуль предоставляет операции сопоставления с регулярными выражениями, аналогичные тем, что есть в Perl. Модуль `re` доступен всегда.1011И шаблоны, и строки для поиска могут быть как строками Unicode, так и 8-битными строками. Однако строки Unicode и 8-битные строки нельзя смешивать: то есть нельзя сопоставить строку Unicode с байтовым шаблоном или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон, и искомая строка.1213В регулярных выражениях обратная косая черта (`'\'`) используется для обозначения специальных форм или чтобы разрешить использование специальных символов без их специального значения. Это противоречит использованию того же символа в Python для той же цели в строковых литералах; например, чтобы сопоставить буквальную обратную косую черту, возможно, придётся написать `'\\\\'` в строке шаблона, потому что регулярное выражение должно быть `\\`, а каждую обратную косую черту нужно выразить как `\\` внутри обычного строкового литерала Python.1415Решение – использовать raw-строки Python для паттернов регулярных выражений; обратная косая черта не обрабатывается особым образом в строковом литерале с префиксом `'r'`. Так что `r"\n"` – это двухсимвольная строка, содержащая `'\'` и `'n'`, в то время как `"\n"` – односимвольная строка, содержащая символ новой строки. Обычно паттерны записывают в коде Python с использованием этой raw-нотации.1617Важно отметить, что большинство операций с регулярными выражениями доступны как функции уровня модуля и методы `RegexObject`. Функции – это сокращения, которые не требуют предварительной компиляции объекта regex, но не имеют некоторых параметров тонкой настройки.1819> **См. также**20>21> **Освоение регулярных выражений**22>23> Книга по регулярным выражениям Джеффри Фридла, издательство O’Reilly. Второе издание книги вообще не охватывает Python, но первое издание очень подробно описывает написание хороших шаблонов регулярных выражений.24>25> **[Kodos](https://python-all.ru/3.0/library/re.html)**26>27> – это графический отладчик регулярных выражений, написанный на Python.2829## Синтаксис регулярных выражений3031Регулярное выражение (или RE) задаёт набор строк, которым оно соответствует; функции в этом модуле позволяют проверить, соответствует ли конкретная строка заданному регулярному выражению (или соответствует ли заданное регулярное выражение конкретной строке – что одно и то же).3233Регулярные выражения можно объединять для получения новых регулярных выражений; если *A* и *B* – регулярные выражения, то *AB* тоже регулярное выражение. В общем, если строка *p* соответствует *A*, а другая строка *q* соответствует *B*, то строка *pq* будет соответствовать AB. Это верно, если только *A* или *B* не содержат операций с низким приоритетом, граничных условий между *A* и *B* или нумерованных обращений к группам. Таким образом, сложные выражения легко строятся из более простых примитивных выражений, подобных описанным здесь. Подробнее о теории и реализации регулярных выражений см. книгу Фридла, указанную выше, или почти любой учебник по построению компиляторов.3435Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более доступного изложения обратитесь к [*руководству по регулярным выражениям*](https://python-all.ru/3.0/howto/regex.html#regex-howto).3637Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, например `'A'`, `'a'` или `'0'`, – это простейшие регулярные выражения: они просто соответствуют сами себе. Можно объединять обычные символы, так что `last` соответствует строке `'last'`. (В остальной части этого раздела мы будем записывать регулярные выражения `таким специальным стилем`, обычно без кавычек, а строки для поиска – `'в одинарных кавычках'`.)3839Некоторые символы, например `'|'` или `'('`, являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на то, как интерпретируются окружающие их регулярные выражения. Строки шаблонов регулярных выражений не могут содержать нулевые байты, но могут задавать нулевой байт с помощью нотации `\number`, например `'\x00'`.4041Специальные символы:4243**`'.'`**4445(Точка.) В режиме по умолчанию соответствует любому символу, кроме перевода строки. Если указан флаг4647[`DOTALL`](https://python-all.ru/3.0/library/re.html#re.DOTALL)4849, соответствует любому символу, включая перевод строки.5051**`'^'`**5253(Циркумфлекс.) Соответствует началу строки, а в режиме5455[`MULTILINE`](https://python-all.ru/3.0/library/re.html#re.MULTILINE)5657также соответствует позиции сразу после каждого перевода строки.5859**`'$'`**6061Соответствует концу строки или позиции перед символом новой строки в конце строки, а в режиме6263[`MULTILINE`](https://python-all.ru/3.0/library/re.html#re.MULTILINE)6465также соответствует перед переводом строки.6667`foo`6869соответствует и 'foo', и 'foobar', а регулярное выражение7071`foo$`7273соответствует только 'foo'. Ещё интереснее: поиск7475`foo.$`7677в7879`'foo1\nfoo2\n'`8081обычно находит 'foo2', но в режиме8283[`MULTILINE`](https://python-all.ru/3.0/library/re.html#re.MULTILINE)8485– 'foo1'; поиск одного8687`$`8889в9091`'foo\n'`9293найдёт два (пустых) совпадения: одно перед переводом строки, и одно в конце строки.9495**`'*'`**9697Заставляет результирующее регулярное выражение соответствовать 0 или более повторениям предшествующего выражения, захватывая максимально возможное количество повторений.9899`ab*`100101будет соответствовать 'a', 'ab' или 'a', за которым следует любое количество 'b'.102103**`'+'`**104105Заставляет результирующее регулярное выражение соответствовать 1 или более повторениям предшествующего выражения.106107`ab+`108109будет соответствовать 'a', за которым следует любое ненулевое количество 'b'; одному 'a' оно не соответствует.110111**`'?'`**112113Заставляет результирующее регулярное выражение соответствовать 0 или 1 повторению предшествующего выражения.114115`ab?`116117будет соответствовать либо 'a', либо 'ab'.118119**`*?`, `+?`, `??`**120121Квантификаторы122123`'*'`124125,126127`'+'`128129и130131`'?'`132133являются134135*жадными*136137; они захватывают максимально возможный текст. Иногда такое поведение нежелательно; если регулярное выражение138139`<.*>`140141применить к строке142143`'<H1>title</H1>'`144145, оно совпадет со всей строкой, а не только с146147`'<H1>'`148149. Добавление150151`'?'`152153после квантификатора заставляет его выполнять сопоставление в154155*нежадном*156157или158159*минимальном*160161режиме; при этом будет захвачено162163*наименьшее количество*164165символов. Используя166167`.*?`168169в предыдущем выражении, мы получим соответствие только170171`'<H1>'`172173.174175**`{m}`**176177Указывает, что должно быть сопоставлено ровно178179*m*180181копий предшествующего регулярного выражения; если совпадений меньше, всё регулярное выражение не срабатывает. Например,182183`a{6}`184185будет соответствовать ровно шести символам186187`'a'`188189, но не пяти.190191**`{m,n}`**192193Заставляет результирующее регулярное выражение соответствовать от194195*m*196197до198199*n*200201повторений предшествующего выражения, пытаясь захватить максимальное количество повторений. Например,202203`a{3,5}`204205будет соответствовать от 3 до 5 символов206207`'a'`208209. Пропуск210211*m*212213задаёт нижнюю границу, равную нулю, а пропуск214215*n*216217– бесконечную верхнюю границу. Например,218219`a{4,}b`220221будет соответствовать222223`aaaab`224225или тысяче символов226227`'a'`228229, за которыми следует230231`b`232233, но не234235`aaab`236237. Запятая не может быть опущена, иначе модификатор будет спутан с ранее описанной формой.238239**`{m,n}?`**240241Заставляет результирующее регулярное выражение соответствовать от242243*m*244245до246247*n*248249повторений предшествующего выражения, пытаясь захватить как можно250251*меньше*252253повторений. Это нежадная версия предыдущего квантификатора. Например, на 6-символьной строке254255`'aaaaaa'`256257выражение258259`a{3,5}`260261совпадет с 5 символами262263`'a'`264265, тогда как266267`a{3,5}?`268269– только с 3.270271**`'\'`**272273Либо экранирует специальные символы (позволяя сопоставлять такие символы, как `'*'`, `'?'` и т.д.), либо обозначает специальную последовательность; специальные последовательности рассматриваются ниже.274275Если вы не используете сырую строку для выражения шаблона, помните, что Python также использует обратную косую черту как escape-последовательность в строковых литералах; если escape- последовательность не распознаётся парсером Python, обратная косая черта и следующий за ней символ включаются в результирующую строку. Однако если Python распознает результирующую последовательность, обратную косую черту следует удвоить. Это сложно и трудно для понимания, поэтому настоятельно рекомендуется использовать сырые строки для всех, кроме самых простых выражений.276277**`[]`**278279Используется для указания набора символов. Символы можно перечислить по отдельности, или диапазон символов можно указать, задав два символа и разделив их символом `'-'`. Специальные символы внутри наборов не действуют. Например, `[akm$]` будет соответствовать любому из символов `'a'`, `'k'`, `'m'` или `'$'`; `[a-z]` будет соответствовать любой строчной букве, а `[a-zA-Z0-9]` – любой букве или цифре. Классы символов, такие как `\w` или `\S` (определённые ниже), также допустимы внутри диапазона, хотя соответствие символов зависит от того, активен ли режим [`ASCII`](https://python-all.ru/3.0/library/re.html#re.ASCII) или [`LOCALE`](https://python-all.ru/3.0/library/re.html#re.LOCALE). Если нужно включить символ `']'` или `'-'` внутрь набора, поставьте перед ним обратную косую черту или поместите его первым символом. Шаблон `[]]` будет соответствовать `']'`, например.280281Можно сопоставлять символы, не входящие в диапазон, *дополняя* набор. Это указывается включением `'^'` в качестве первого символа набора; `'^'` в другом месте просто будет соответствовать символу `'^'`. Например, `[^5]` будет соответствовать любому символу, кроме `'5'`, а `[^^]` будет соответствовать любому символу, кроме `'^'`.282283Обратите внимание, что внутри `[]` специальные формы и специальные символы теряют свой смысл, и допустимы только описанные здесь синтаксисы. Например, `+`, `*`, `(`, `)` и так далее трактуются как литералы внутри `[]`, а обратные ссылки нельзя использовать внутри `[]`.284285**`'|'`**286287`A|B`288289, где A и B могут быть произвольными регулярными выражениями, создает регулярное выражение, которое будет соответствовать либо A, либо B. Таким способом можно разделять произвольное количество регулярных выражений с помощью290291`'|'`292293. Это можно использовать и внутри групп (см. ниже). При сканировании целевой строки выражения, разделенные294295`'|'`296297, пробуются слева направо. Когда один паттерн полностью совпадает, эта ветвь принимается. Это означает, что как только298299`A`300301совпадает,302303`B`304305больше не проверяется, даже если оно дало бы более длинное совпадение. Другими словами, оператор306307`'|'`308309никогда не бывает жадным. Чтобы сопоставить литерал310311`'|'`312313, используйте314315`\|`316317или заключите его в символьный класс, например318319`[|]`320321.322323**`(...)`**324325Соответствует любому регулярному выражению внутри скобок и обозначает начало и конец группы; содержимое группы можно получить после выполнения сопоставления, а также сопоставить позже в строке с помощью специальной последовательности326327`\number`328329, описанной ниже. Чтобы сопоставить литералы330331`'('`332333или334335`')'`336337, используйте338339`\(`340341или342343`\)`344345, или заключите их в символьный класс:346347`[(] [)]`348349.350351**`(?...)`**352353Это нотация расширения (354355`'?'`356357после358359`'('`360361в противном случае не имеет смысла). Первый символ после362363`'?'`364365определяет значение и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу;366367`(?P<name>...)`368369– единственное исключение из этого правила. Ниже перечислены поддерживаемые в настоящее время расширения.370371**`(?aiLmsux)`**372373(Одна или несколько букв из набора `'a'`, `'i'`, `'L'`, `'m'`, `'s'`, `'u'`, `'x'`.) Группа сопоставляется с пустой строкой; буквы устанавливают соответствующие флаги: `re.a` (только ASCII), [`re.I`](https://python-all.ru/3.0/library/re.html#re.I) (игнорировать регистр), [`re.L`](https://python-all.ru/3.0/library/re.html#re.L) (зависит от локали), [`re.M`](https://python-all.ru/3.0/library/re.html#re.M) (многострочный), [`re.S`](https://python-all.ru/3.0/library/re.html#re.S) (точка совпадает с любым символом), и [`re.X`](https://python-all.ru/3.0/library/re.html#re.X) (подробный) для всего регулярного выражения. (Флаги описаны в [*Содержимое модуля*](https://python-all.ru/3.0/library/re.html#contents-of-module-re).) Это полезно, если вы хотите включить флаги как часть регулярного выражения, вместо передачи аргумента *флаг* в функцию [`compile()`](https://python-all.ru/3.0/library/functions.html#compile).374375Обратите внимание, что флаг `(?x)` изменяет способ разбора выражения. Он должен быть указан первым в строке выражения или после одного или нескольких пробельных символов. Если перед флагом есть непробельные символы, результат не определён.376377**`(?:...)`**378379Негруппирующая версия круглых скобок. Совпадает с любым регулярным выражением внутри скобок, но подстрока, совпавшая с группой,380381*не может*382383быть извлечена после выполнения сопоставления или использована позже в шаблоне.384385**`(?P<name>...)`**386387Подобно обычным круглым скобкам, но подстрока, совпавшая с группой, доступна по символическому имени группы *name*. Имена групп должны быть допустимыми идентификаторами Python, и каждое имя группы должно быть определено только один раз в пределах регулярного выражения. Символическая группа также является пронумерованной группой, как если бы группа не была именованной. Таким образом, группу с именем 'id' в примере ниже также можно ссылаться как на пронумерованную группу 1.388389Например, если шаблон `(?P<id>[a-zA-Z_]\w*)`, на группу можно ссылаться по имени в аргументах методов объектов сопоставления, таких как `m.group('id')` или `m.end('id')`, а также по имени в тексте шаблона (например, `(?P=id)`) и в тексте замены (например, `\g<id>`).390391**`(?P=name)`**392393Совпадает с любым текстом, который совпал с ранее определённой группой с именем394395*name*396397.398399**`(?#...)`**400401Комментарий; содержимое скобок просто игнорируется.402403**`(?=...)`**404405Совпадает, если406407`...`408409совпадает далее, но не поглощает ни одного символа строки. Это называется опережающей проверкой. Например,410411`Isaac (?=Asimov)`412413совпадёт с414415`'Isaac '`416417только если за ним следует418419`'Asimov'`420421.422423**`(?!...)`**424425Совпадает, если426427`...`428429не совпадает далее. Это отрицательная опережающая проверка. Например,430431`Isaac (?!Asimov)`432433совпадёт с434435`'Isaac '`436437только если за ним438439*не*440441следует442443`'Asimov'`444445.446447**`(?<=...)`**448449Совпадение, если текущей позиции в строке предшествует совпадение с `...`, которое заканчивается на текущей позиции. Это называется *положительной ретроспективной проверкой (lookbehind)*. `(?<=abc)def` найдёт совпадение в `abcdef`, поскольку ретроспективная проверка отступит на 3 символа и проверит, соответствует ли вложенный шаблон. Вложенный шаблон должен соответствовать строкам только фиксированной длины, то есть `abc` или `a|b` допустимы, а `a*` и `a{3,4}` – нет. Обратите внимание, что шаблоны, начинающиеся с положительной ретроспективной проверки, никогда не будут совпадать в начале искомой строки; скорее всего, потребуется использовать функцию [`search()`](https://python-all.ru/3.0/library/re.html#re.search), а не [`match()`](https://python-all.ru/3.0/library/re.html#re.match).450451```python452>>> import re453>>> m = re.search('(?<=abc)def', 'abcdef')454>>> m.group(0)455'def'456```457458Этот пример ищет слово, следующее за дефисом:459460```python461>>> m = re.search('(?<=-)\w+', 'spam-egg')462>>> m.group(0)463'egg'464```465466**`(?<!...)`**467468Совпадает, если текущей позиции в строке не предшествует совпадение с469470`...`471472. Это называется473474*отрицательной ретроспективной проверкой*475476. Аналогично положительным ретроспективным проверкам, вложенный шаблон может соответствовать только строкам фиксированной длины. Шаблоны, начинающиеся с отрицательной ретроспективной проверки, могут совпадать в начале искомой строки.477478**`(?(id/name)yes-pattern|no-pattern)`**479480Пытается сопоставиться с481482`yes-pattern`483484, если группа с данным485486*id*487488или489490*name*491492существует, и с493494`no-pattern`495496, если она не существует.497498`no-pattern`499500является необязательным и может быть опущен. Например,501502`(<)?(\w+@\w+(?:\.\w+)+)(?(1)>)`503504– это плохой шаблон для сопоставления email, который будет совпадать с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.0/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.0/library/re.html#re.ASCII)601602.603604**`\d`**605606**Для шаблонов Unicode (str):**607608Соответствует любой цифре Unicode (включая609610`[0-9]`611612, а также многие другие цифровые символы). Если используется флаг613614[`ASCII`](https://python-all.ru/3.0/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.0/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.0/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.0/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.0/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.0/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## Сопоставление и поиск765766Python предлагает две различные примитивные операции на основе регулярных выражений: **match** проверяет совпадение только в начале строки, тогда как **search** проверяет совпадение в любом месте строки (именно так по умолчанию работает Perl).767768Обратите внимание, что match может отличаться от search, даже если используется регулярное выражение, начинающееся с `'^'`: `'^'` совпадает только в начале строки или в режиме [`MULTILINE`](https://python-all.ru/3.0/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## Содержимое модуля777778Модуль определяет несколько функций, констант и одно исключение. Некоторые из функций являются упрощёнными версиями полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используется скомпилированная форма.779780#### `[re.compile]re.compile(pattern[, flags])`781782Компилирует шаблон регулярного выражения в объект регулярного выражения, который можно использовать для поиска совпадений с помощью его методов [`match()`](https://python-all.ru/3.0/library/re.html#re.match) и [`search()`](https://python-all.ru/3.0/library/re.html#re.search), описанных ниже.783784Поведение выражения можно изменить, указав значение *flags*. В качестве значений можно использовать любые из следующих переменных, комбинируя их с помощью побитового ИЛИ (оператор `|`).785786Последовательность787788```python789prog = re.compile(pat)790result = prog.match(str)791```792793эквивалентна794795```python796result = re.match(pat, str)797```798799но версия с использованием [`compile()`](https://python-all.ru/3.0/library/functions.html#compile) более эффективна, когда выражение будет использоваться несколько раз в одной программе.800801#### `[re.A]re.A`802803#### `re.ASCII`804805Заставляет `\\w`, `\\W`, `\\b`, `\\B`, `\\s` и `\\S` выполнять сопоставление только по ASCII вместо полного сопоставления Unicode. Это имеет смысл только для шаблонов Unicode и игнорируется для байтовых шаблонов.806807Обратите внимание, что для обратной совместимости флаг `re.U` всё ещё существует (наряду с его синонимом `re.UNICODE` и встроенным вариантом `(?u)`), но они избыточны в Python 3.0, так как по умолчанию для строк совпадения ищутся в Unicode (а сопоставление в Unicode не допускается для bytes).808809#### `[re.I]re.I`810811#### `re.IGNORECASE`812813Выполняет сопоставление без учёта регистра; выражения вроде814815`[A-Z]`816817будут соответствовать также и строчным буквам. На это не влияет текущая локаль, и оно работает с символами Unicode так, как и ожидается.818819#### `[re.L]re.L`820821#### `re.LOCALE`822823Делает824825`\w`826827,828829`\W`830831,832833`\b`834835,836837`\B`838839,840841`\s`842843и844845`\S`846847зависимыми от текущей локали. Использование этого флага не рекомендуется, так как механизм локали очень ненадёжен и к тому же обрабатывает только одну «культуру» за раз; вместо этого следует использовать сопоставление в Unicode, которое является по умолчанию в Python 3.0 для шаблонов Unicode (str).848849#### `[re.M]re.M`850851#### `re.MULTILINE`852853При указании этого флага символ шаблона854855`'^'`856857совпадает с началом строки и с началом каждой строки (сразу после каждого перевода строки); а символ шаблона858859`'$'`860861совпадает с концом строки и с концом каждой строки (непосредственно перед каждым переводом строки). По умолчанию862863`'^'`864865совпадает только с началом строки, а866867`'$'`868869– только с концом строки и непосредственно перед переводом строки (если он есть) в конце строки.870871#### `[re.S]re.S`872873#### `re.DOTALL`874875Заставляет специальный символ876877`'.'`878879совпадать с любым символом, включая перевод строки; без этого флага880881`'.'`882883будет совпадать с любым символом,884885*кроме*886887перевода строки.888889#### `[re.X]re.X`890891#### `re.VERBOSE`892893Этот флаг позволяет писать более читаемые регулярные выражения. Пробельные символы в шаблоне игнорируются, кроме случаев, когда они находятся внутри символьного класса или перед ними стоит неэкранированная обратная косая черта. Кроме того, если строка содержит `'#'`, не находящийся в символьном классе и не предварённый неэкранированной обратной косой чертой, все символы от самого левого такого `'#'` до конца строки игнорируются.894895Это означает, что следующие два объекта регулярных выражений, которые соответствуют десятичному числу, функционально эквивалентны:896897```python898a = re.compile(r"""\d + # the integral part899 \. # the decimal point900 \d * # some fractional digits""", re.X)901b = re.compile(r"\d+\.\d*")902```903904#### `[re.search]re.search(pattern, string[, flags])`905906Сканирует907908*string*909910в поиске позиции, где регулярное выражение911912*pattern*913914даёт совпадение, и возвращает соответствующий экземпляр915916`MatchObject`917918. Возвращает919920`None`921922, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в некоторой точке строки.923924#### `[re.match]re.match(pattern, string[, flags])`925926Если ноль или более символов в начале *string* соответствуют регулярному выражению *pattern*, возвращает соответствующий экземпляр `MatchObject`. Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.927928> **Примечание**929>930> Если нужно найти совпадение в любом месте *string*, используйте [`search()`](https://python-all.ru/3.0/library/re.html#re.search) вместо этого.931932#### `[re.split]re.split(pattern, string[, maxsplit=0])`933934Разделяет *string* по вхождениям *pattern*. Если в *pattern* используются захватывающие круглые скобки, то текст всех групп в шаблоне также возвращается как часть результирующего списка. Если *maxsplit* не равно нулю, то происходит не более *maxsplit* разбиений, а остаток строки возвращается как последний элемент списка.935936```python937>>> re.split('\W+', 'Words, words, words.')938['Words', 'words', 'words', '']939>>> re.split('(\W+)', 'Words, words, words.')940['Words', ', ', 'words', ', ', 'words', '.', '']941>>> re.split('\W+', 'Words, words, words.', 1)942['Words', 'words, words.']943```944945Если в разделителе есть захватывающие группы и он совпадает в начале строки, результат будет начинаться с пустой строки. То же самое относится и к концу строки:946947```python948>>> re.split('(\W+)', '...words, words...')949['', '...', 'words', ', ', 'words', '...', '']950```951952Таким образом, компоненты разделителя всегда находятся на одних и тех же относительных позициях в результирующем списке (например, если в разделителе есть одна захватывающая группа, то на 0-м, 2-м и так далее).953954Обратите внимание, что *split* никогда не разделяет строку по пустому совпадению шаблона. Например:955956```python957>>> re.split('x*', 'foo')958['foo']959>>> re.split("(?m)^$", "foo\n\nbar\n")960['foo\n\nbar\n']961```962963#### `[re.findall]re.findall(pattern, string[, flags])`964965Возвращает все непересекающиеся совпадения966967*pattern*968969в970971*string*972973, в виде списка строк. Строка974975*string*976977сканируется слева направо, совпадения возвращаются в порядке обнаружения. Если в шаблоне присутствуют одна или несколько групп, возвращается список групп; если групп больше одной – список кортежей. Пустые совпадения включаются в результат, кроме случаев, когда они примыкают к началу другого совпадения.978979#### `[re.finditer]re.finditer(pattern, string[, flags])`980981Возвращает982983[*iterator*](https://python-all.ru/3.0/glossary.html#term-iterator)984985, выдающий экземпляры986987`MatchObject`988989для всех неперекрывающихся совпадений регулярного выражения990991*pattern*992993в994995*string*996997.998999*string*10001001сканируется слева направо, и совпадения возвращаются в порядке их обнаружения. Пустые совпадения включаются в результат, если только они не касаются начала другого совпадения.10021003#### `[re.sub]re.sub(pattern, repl, string[, count])`10041005Возвращает строку, полученную заменой крайних левых непересекающихся вхождений *pattern* в *string* на замену *repl*. Если шаблон не найден, *string* возвращается без изменений. *repl* может быть строкой или функцией; если это строка, все управляющие последовательности в ней обрабатываются. То есть `\n` преобразуется в символ новой строки, `\r` преобразуется в символ возврата каретки и так далее. Неизвестные управляющие последовательности, такие как `\j`, остаются без изменений. Обратные ссылки, такие как `\6`, заменяются подстрокой, совпавшей с группой 6 в шаблоне. Например:10061007```python1008>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',1009... r'static PyObject*\npy_\1(void)\n{',1010... 'def myfunc():')1011'static PyObject*\npy_myfunc(void)\n{'1012```10131014Если *repl* – функция, она вызывается для каждого непересекающегося вхождения *pattern*. Функция принимает один аргумент – объект совпадения – и возвращает строку замены. Например:10151016```python1017>>> def dashrepl(matchobj):1018... if matchobj.group(0) == '-': return ' '1019... else: return '-'1020>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')1021'pro--gram files'1022```10231024Шаблон может быть строкой или объектом RE; если необходимо указать флаги регулярного выражения, следует использовать объект RE или встроенные модификаторы в шаблоне; например, `sub("(?i)b+", "x", "bbbb BBBB")` возвращает `'x x'`.10251026Необязательный аргумент *count* – это максимальное количество заменяемых вхождений шаблона; *count* должен быть неотрицательным целым числом. Если опущено или равно нулю, заменяются все вхождения. Пустые совпадения шаблона заменяются только тогда, когда они не примыкают к предыдущему совпадению, поэтому `sub('x*', '-', 'abc')` возвращает `'-a-b-c-'`.10271028В дополнение к экранированию символов и обратным ссылкам, описанным выше, `\g<name>` будет использовать подстроку, совпавшую с группой с именем `name`, как определено синтаксисом `(?P<name>...)`. `\g<number>` использует соответствующий номер группы; `\g<2>` поэтому эквивалентно `\2`, но не является неоднозначным в замене, такой как `\g<2>0`. `\20` было бы интерпретировано как ссылка на группу 20, а не ссылка на группу 2, за которой следует литерал `'0'`. Обратная ссылка `\g<0>` подставляет всю подстроку, совпавшую с регулярным выражением.10291030#### `[re.subn]re.subn(pattern, repl, string[, count])`10311032Выполняет ту же операцию, что и10331034[`sub()`](https://python-all.ru/3.0/library/re.html#re.sub)10351036, но возвращает кортеж10371038`(new_string, number_of_subs_made)`10391040.10411042#### `[re.escape]re.escape(string)`10431044Возвращает10451046*string*10471048, в котором все небуквенно-цифровые символы экранированы обратной косой чертой; это полезно, если требуется найти произвольную литеральную строку, которая может содержать метасимволы регулярных выражений.10491050#### `[re.error]exception re.error`10511052Исключение возникает, когда строка, переданная одной из функций здесь, не является допустимым регулярным выражением (например, может содержать непарные скобки) или когда происходит другая ошибка во время компиляции или сопоставления. Это никогда не является ошибкой, если строка не содержит совпадений с шаблоном.10531054## Объекты регулярных выражений10551056Скомпилированные объекты регулярных выражений поддерживают следующие методы и атрибуты:10571058#### `[re.RegexObject.match]RegexObject.match(string[, pos[, endpos]])`10591060Если ноль или более символов в начале *string* соответствуют данному регулярному выражению, возвращает соответствующий экземпляр `MatchObject`. Возвращает `None`, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.10611062> **Примечание**1063>1064> Если нужно найти совпадение в любом месте *string*, используйте [`search()`](https://python-all.ru/3.0/library/re.html#re.search) вместо этого.10651066Необязательный второй параметр *pos* задаёт индекс в строке, с которого начинается поиск; по умолчанию `0`. Это не полностью эквивалентно срезу строки; символ шаблона `'^'` сопоставляется с реальным началом строки и с позициями сразу после символа новой строки, но не обязательно с индексом, с которого должен начинаться поиск.10671068Необязательный параметр *endpos* ограничивает глубину поиска по строке; строка рассматривается как имеющая длину *endpos* символов, поэтому для поиска совпадения будут использоваться только символы от *pos* до `endpos - 1`. Если *endpos* меньше *pos*, совпадение не будет найдено; в противном случае, если *rx* является скомпилированным объектом регулярного выражения, `rx.match(string, 0, 50)` эквивалентно `rx.match(string[:50], 0)`.10691070```python1071>>> pattern = re.compile("o")1072>>> pattern.match("dog") # Нет совпадения, так как "o" не находится в начале строки "dog."1073>>> pattern.match("dog", 1) # Совпадение есть, так как "o" – второй символ строки "dog".1074<_sre.SRE_Match object at ...>1075```10761077#### `[re.RegexObject.search]RegexObject.search(string[, pos[, endpos]])`10781079Сканирует *string* в поиске позиции, где данное регулярное выражение даёт совпадение, и возвращает соответствующий экземпляр `MatchObject`. Возвращает `None`, если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в некоторой точке строки.10801081Необязательные параметры *pos* и *endpos* имеют тот же смысл, что и для метода [`match()`](https://python-all.ru/3.0/library/re.html#re.match).10821083#### `[re.RegexObject.split]RegexObject.split(string[, maxsplit=0])`10841085Идентично функции10861087[`split()`](https://python-all.ru/3.0/library/re.html#re.split)10881089, используя скомпилированный шаблон.10901091#### `[re.RegexObject.findall]RegexObject.findall(string[, pos[, endpos]])`10921093Идентична функции10941095[`findall()`](https://python-all.ru/3.0/library/re.html#re.findall)10961097, но использует скомпилированный шаблон.10981099#### `[re.RegexObject.finditer]RegexObject.finditer(string[, pos[, endpos]])`11001101Идентична функции11021103[`finditer()`](https://python-all.ru/3.0/library/re.html#re.finditer)11041105, но использует скомпилированный шаблон.11061107#### `[re.RegexObject.sub]RegexObject.sub(repl, string[, count=0])`11081109Идентична функции11101111[`sub()`](https://python-all.ru/3.0/library/re.html#re.sub)11121113, использующей скомпилированный шаблон.11141115#### `[re.RegexObject.subn]RegexObject.subn(repl, string[, count=0])`11161117Идентична функции11181119[`subn()`](https://python-all.ru/3.0/library/re.html#re.subn)11201121, использующей скомпилированный шаблон.11221123#### `[re.RegexObject.flags]RegexObject.flags`11241125Аргумент flags, использованный при компиляции объекта RE, или11261127`0`11281129, если флаги не были указаны.11301131#### `[re.RegexObject.groups]RegexObject.groups`11321133Количество захватываемых групп в шаблоне.11341135#### `[re.RegexObject.groupindex]RegexObject.groupindex`11361137Словарь, сопоставляющий любые символьные имена групп, определённые с помощью11381139`(?P<id>)`11401141, с номерами групп. Словарь пуст, если в шаблоне не использовались символьные группы.11421143#### `[re.RegexObject.pattern]RegexObject.pattern`11441145Строка шаблона, из которой был скомпилирован объект RE.11461147## Объекты Match11481149Объекты Match всегда имеют логическое значение [`True`](https://python-all.ru/3.0/library/constants.html#True), поэтому можно проверить, например, с помощью простого оператора if, дал ли [`match()`](https://python-all.ru/3.0/library/re.html#re.match) совпадение. Они поддерживают следующие методы и атрибуты:11501151#### `[re.MatchObject.expand]MatchObject.expand(template)`11521153Возвращает строку, полученную путём подстановки с обратной косой чертой в строке шаблона11541155*template*11561157, как это делает метод11581159[`sub()`](https://python-all.ru/3.0/library/re.html#re.sub)11601161. Управляющие последовательности, такие как11621163`\n`11641165, преобразуются в соответствующие символы, а числовые обратные ссылки (11661167`\1`11681169,11701171`\2`11721173) и именованные обратные ссылки (11741175`\g<1>`11761177,11781179`\g<name>`11801181) заменяются содержимым соответствующей группы.11821183#### `[re.MatchObject.group]MatchObject.group([group1, ...])`11841185Возвращает одну или несколько подгрупп совпадения. Если аргумент один, результатом является одна строка; если аргументов несколько, результат – кортеж с одним элементом на каждый аргумент. Без аргументов *group1* по умолчанию равен нулю (возвращается всё совпадение). Если аргумент *groupN* равен нулю, соответствующее возвращаемое значение – вся сопоставленная строка; если он находится в диапазоне \[1..99\] включительно, это строка, соответствующая соответствующей группе в скобках. Если номер группы отрицателен или больше количества групп, определённых в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IndexError). Если группа содержится в части шаблона, которая не совпала, соответствующий результат равен `None`. Если группа содержится в части шаблона, которая совпала несколько раз, возвращается последнее совпадение.11861187```python1188>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")1189>>> m.group(0) # Всё совпадение1190'Isaac Newton'1191>>> m.group(1) # Первая группа в скобках.1192'Isaac'1193>>> m.group(2) # Вторая группа в скобках.1194'Newton'1195>>> m.group(1, 2) # Несколько аргументов дают кортеж.1196('Isaac', 'Newton')1197```11981199Если в регулярном выражении используется синтаксис `(?P<name>...)`, то аргументы *groupN* могут также быть строками, идентифицирующими группы по их имени. Если строковый аргумент не используется как имя группы в шаблоне, возбуждается исключение [`IndexError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IndexError).12001201Довольно сложный пример:12021203```python1204>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcom Reynolds")1205>>> m.group('first_name')1206'Malcom'1207>>> m.group('last_name')1208'Reynolds'1209```12101211Именованные группы также можно указывать по их индексу:12121213```python1214>>> m.group(1)1215'Malcom'1216>>> m.group(2)1217'Reynolds'1218```12191220Если группа совпадает несколько раз, доступно только последнее совпадение:12211222```python1223>>> m = re.match(r"(..)+", "a1b2c3") # Совпадает 3 раза.1224>>> m.group(1) # Возвращает только последнее совпадение.1225'c3'1226```12271228#### `[re.MatchObject.groups]MatchObject.groups([default])`12291230Возвращает кортеж, содержащий все подгруппы совпадения, от 1 до количества групп в шаблоне. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`.12311232Например:12331234```python1235>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")1236>>> m.groups()1237('24', '1632')1238```12391240Если сделать десятичную точку и всё после неё необязательными, не все группы могут участвовать в совпадении. Эти группы по умолчанию будут равны `None`, если не указан аргумент *default*:12411242```python1243>>> m = re.match(r"(\d+)\.?(\d+)?", "24")1244>>> m.groups() # Вторая группа по умолчанию – None.1245('24', None)1246>>> m.groups('0') # Теперь вторая группа по умолчанию – '0'.1247('24', '0')1248```12491250#### `[re.MatchObject.groupdict]MatchObject.groupdict([default])`12511252Возвращает словарь, содержащий все *именованные* подгруппы совпадения, где ключом является имя подгруппы. Аргумент *default* используется для групп, которые не участвовали в совпадении; по умолчанию он равен `None`. Например:12531254```python1255>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcom Reynolds")1256>>> m.groupdict()1257{'first_name': 'Malcom', 'last_name': 'Reynolds'}1258```12591260#### `[re.MatchObject.start]MatchObject.start([group])`12611262#### `MatchObject.end([group])`12631264Возвращает индексы начала и конца подстроки, сопоставленной с *group*; *group* по умолчанию равен нулю (означает всю сопоставленную подстроку). Возвращает `-1`, если *group* существует, но не участвовал в совпадении. Для объекта совпадения *m* и группы *g*, которая участвовала в совпадении, подстрока, сопоставленная группой *g* (эквивалент `m.group(g)`), – это12651266```python1267m.string[m.start(g):m.end(g)]1268```12691270Обратите внимание, что `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.0/library/exceptions.html#exceptions.IndexError).12711272Пример, который удалит *remove\_this* из адресов электронной почты:12731274```python1275>>> email = "tony@tiremove_thisger.net"1276>>> m = re.search("remove_this", email)1277>>> email[:m.start()] + email[m.end():]1278'tony@tiger.net'1279```12801281#### `[re.MatchObject.span]MatchObject.span([group])`12821283Для12841285`MatchObject`12861287*m*12881289возвращает кортеж из двух элементов12901291`(m.start(group), m.end(group))`12921293. Обратите внимание: если12941295*group*12961297не участвовала в сопоставлении, результатом будет12981299`(-1, -1)`13001301.13021303*group*13041305по умолчанию равен нулю (всё совпадение).13061307#### `[re.MatchObject.pos]MatchObject.pos`13081309Значение13101311*pos*13121313, переданное методу13141315[`search()`](https://python-all.ru/3.0/library/re.html#re.search)13161317или13181319[`match()`](https://python-all.ru/3.0/library/re.html#re.match)13201321объекта13221323`RegexObject`13241325. Это индекс в строке, начиная с которого механизм регулярных выражений начал искать совпадение.13261327#### `[re.MatchObject.endpos]MatchObject.endpos`13281329Значение13301331*endpos*13321333, переданное методу13341335[`search()`](https://python-all.ru/3.0/library/re.html#re.search)13361337или13381339[`match()`](https://python-all.ru/3.0/library/re.html#re.match)13401341объекта13421343`RegexObject`13441345. Это индекс в строке, за который механизм регулярных выражений не выходит.13461347#### `[re.MatchObject.lastindex]MatchObject.lastindex`13481349Целочисленный индекс последней совпавшей захватывающей группы или13501351`None`13521353, если ни одна группа не совпала. Например, выражения13541355`(a)b`13561357,13581359`((a)(b))`13601361и13621363`((ab))`13641365будут иметь13661367`lastindex == 1`13681369, если применить к строке13701371`'ab'`13721373, а выражение13741375`(a)(b)`13761377будет иметь13781379`lastindex == 2`13801381, если применить к той же строке.13821383#### `[re.MatchObject.lastgroup]MatchObject.lastgroup`13841385Имя последней совпавшей захватывающей группы или13861387`None`13881389, если у группы не было имени или если ни одна группа не совпала.13901391#### `[re.MatchObject.re]MatchObject.re`13921393Объект регулярного выражения, чей метод13941395[`match()`](https://python-all.ru/3.0/library/re.html#re.match)13961397или13981399[`search()`](https://python-all.ru/3.0/library/re.html#re.search)14001401создал данный экземпляр14021403`MatchObject`14041405.14061407#### `[re.MatchObject.string]MatchObject.string`14081409Строка, переданная методу14101411[`match()`](https://python-all.ru/3.0/library/re.html#re.match)14121413или14141415[`search()`](https://python-all.ru/3.0/library/re.html#re.search)14161417.14181419## Примеры14201421### Проверка на пару14221423В этом примере используется следующая вспомогательная функция для более наглядного отображения объектов совпадения:14241425```python1426def displaymatch(match):1427 if match is None:1428 return None1429 return '<Match: %r, groups=%r>' % (match.group(), match.groups())1430```14311432Предположим, вы пишете программу для покера, где рука игрока представлена в виде строки из 5 символов, каждый символ обозначает карту: «a» – туз, «k» – король, «q» – дама, j – валет, «0» – десятка, а «1»–«9» – карты с соответствующим номиналом.14331434Чтобы проверить, является ли заданная строка допустимой рукой, можно поступить следующим образом:14351436```python1437>>> valid = re.compile(r"[0-9akqj]{5}$")1438>>> displaymatch(valid.match("ak05q")) # Допустимо.1439"<Match: 'ak05q', groups=()>"1440>>> displaymatch(valid.match("ak05e")) # Недопустимо.1441>>> displaymatch(valid.match("ak0")) # Недопустимо.1442>>> displaymatch(valid.match("727ak")) # Допустимо.1443"<Match: '727ak', groups=()>"1444```14451446Та последняя рука, `"727ak"`, содержала пару, то есть две карты одного достоинства. Чтобы сопоставить это с помощью регулярного выражения, можно использовать обратные ссылки следующим образом:14471448```python1449>>> pair = re.compile(r".*(.).*\1")1450>>> displaymatch(pair.match("717ak")) # Пара семёрок.1451"<Match: '717', groups=('7',)>"1452>>> displaymatch(pair.match("718ak")) # Нет пар.1453>>> displaymatch(pair.match("354aa")) # Пара тузов.1454"<Match: '354aa', groups=('a',)>"1455```14561457Чтобы узнать, из какого совпадения состоит пара, можно использовать метод `group()` объекта `MatchObject` следующим образом:14581459```python1460>>> pair.match("717ak").group(1)1461'7'14621463# Error because re.match() returns None, which doesn't have a group() method:1464>>> pair.match("718ak").group(1)1465Traceback (most recent call last):1466 File "<pyshell#23>", line 1, in <module>1467 re.match(r".*(.).*\1", "718ak").group(1)1468AttributeError: 'NoneType' object has no attribute 'group'14691470>>> pair.match("354aa").group(1)1471'a'1472```14731474### Эмуляция scanf()14751476В Python на данный момент нет аналога `scanf`. Регулярные выражения, как правило, мощнее, хотя и более многословны, чем строки форматирования `scanf`. В таблице ниже приведены некоторые более-менее эквивалентные соответствия между токенами формата `scanf` и регулярными выражениями.14771478| Токен `scanf` | Регулярное выражение |1479| --- | --- |1480| `%c` | `.` |1481| `%5c` | `.{5}` |1482| `%d` | `[-+]?\d+` |1483| `%e`, `%E`, `%f`, `%g` | `[-+]?(\d+(\.\d*)?\|\.\d+)([eE][-+]?\d+)?` |1484| `%i` | `[-+]?(0[xX][\dA-Fa-f]+\|0[0-7]*\|\d+)` |1485| `%o` | `0[0-7]*` |1486| `%s` | `\S+` |1487| `%u` | `\d+` |1488| `%x`, `%X` | `0[xX][\dA-Fa-f]+` |14891490Чтобы извлечь имя файла и числа из строки вида14911492```python1493/usr/sbin/sendmail - 0 errors, 4 warnings1494```14951496можно использовать формат `scanf`, например14971498```python1499%s - %d errors, %d warnings1500```15011502Эквивалентное регулярное выражение будет15031504```python1505(\S+) - (\d+) errors, (\d+) warnings1506```15071508### Избегание рекурсии15091510Если вы создаёте регулярные выражения, требующие от движка выполнения большого объёма рекурсии, может возникнуть исключение [`RuntimeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.RuntimeError) с сообщением `maximum recursion limit` exceeded. Например,15111512```python1513>>> s = 'Begin ' + 1000*'a very long string ' + 'end'1514>>> re.match('Begin (\w| )*? end', s).end()1515Traceback (most recent call last):1516 File "<stdin>", line 1, in ?1517 File "/usr/local/lib/python2.5/re.py", line 132, in match1518 return _compile(pattern, flags).match(string)1519RuntimeError: maximum recursion limit exceeded1520```15211522Часто можно перестроить регулярное выражение, чтобы избежать рекурсии.15231524Простые случаи использования шаблона `*?` обрабатываются особым образом, чтобы избежать рекурсии. Таким образом, указанное выше регулярное выражение может избежать рекурсии, если его переписать как `Begin [a-zA-Z0-9_ ]*?end`. В качестве дополнительного преимущества такие регулярные выражения будут работать быстрее, чем их рекурсивные аналоги.15251526### search() и match()15271528В двух словах, [`match()`](https://python-all.ru/3.0/library/re.html#re.match) пытается сопоставить шаблон только в начале строки, тогда как [`search()`](https://python-all.ru/3.0/library/re.html#re.search) находит шаблон в любом месте строки. Например:15291530```python1531>>> re.match("o", "dog") # Совпадение отсутствует, так как «o» не является первой буквой слова «dog».1532>>> re.search("o", "dog") # Совпадение найдено, так как search() ищет по всей строке.1533<_sre.SRE_Match object at ...>1534```15351536> **Примечание**1537>1538> Следующее относится только к объектам регулярных выражений, созданным с помощью `re.compile("pattern")`, а не к примитивам `re.match(pattern, string)` или `re.search(pattern, string)`.15391540У [`match()`](https://python-all.ru/3.0/library/re.html#re.match) есть необязательный второй параметр, который задаёт индекс в строке, с которого должен начинаться поиск:15411542> ```python1543> >>> pattern = re.compile("o")1544> >>> pattern.match("dog") # Нет совпадения, так как "o" не находится в начале строки "dog."1545> ```1546>1547> # Эквивалентно приведенному выше выражению, так как 0 – это начальный индекс по умолчанию: \>\>\> pattern.match(“dog”, 0)1548>1549> # Совпадение, так как “o” – второй символ “dog” (индекс 0 – первый): \>\>\> pattern.match(“dog”, 1) \<\_sre.SRE\_Match object at ...\> \>\>\> pattern.match(“dog”, 2) # Нет совпадения, так как “o” не третий символ “dog”.15501551### Создание телефонной книги15521553[`split()`](https://python-all.ru/3.0/library/re.html#re.split) разбивает строку на список, используя переданный шаблон в качестве разделителя. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые Python может легко читать и изменять, как показано в следующем примере, создающем телефонный справочник.15541555Сначала – входные данные. Обычно они берутся из файла, здесь мы используем синтаксис тройных кавычек:15561557```python1558>>> input = """Ross McFluff: 834.345.1254 155 Elm Street1559...1560... Ronald Heathmore: 892.345.3428 436 Finley Avenue1561... Frank Burger: 925.541.7625 662 South Dogwood Way1562...1563...1564... Heather Albrecht: 548.326.4584 919 Park Place"""1565```15661567Записи разделяются одним или несколькими символами новой строки. Теперь преобразуем строку в список, где каждая непустая строка будет отдельной записью:15681569```python1570>>> entries = re.split("\n+", input)1571>>> entries1572['Ross McFluff: 834.345.1254 155 Elm Street',1573'Ronald Heathmore: 892.345.3428 436 Finley Avenue',1574'Frank Burger: 925.541.7625 662 South Dogwood Way',1575'Heather Albrecht: 548.326.4584 919 Park Place']1576```15771578Наконец, каждая запись разбивается на список, содержащий имя, фамилию, номер телефона и адрес. Используется параметр `maxsplit` функции [`split()`](https://python-all.ru/3.0/library/re.html#re.split), потому что адрес содержит пробелы – наш разделитель:15791580```python1581>>> [re.split(":? ", entry, 3) for entry in entries]1582[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],1583['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],1584['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],1585['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]1586```15871588Шаблон `:?` соответствует двоеточию после фамилии, поэтому оно не попадает в результирующий список. С помощью `maxsplit`, равного `4`, можно отделить номер дома от названия улицы:15891590```python1591>>> [re.split(":? ", entry, 4) for entry in entries]1592[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],1593['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],1594['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],1595['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]1596```15971598### Обработка текста15991600[`sub()`](https://python-all.ru/3.0/library/re.html#re.sub) заменяет каждое вхождение шаблона на строку или результат функции. В этом примере показано использование [`sub()`](https://python-all.ru/3.0/library/re.html#re.sub) с функцией для «изменения» (munge) текста, то есть перемешивания порядка всех символов в каждом слове предложения, кроме первого и последнего:16011602```python1603>>> def repl(m):1604... inner_word = list(m.group(2))1605... random.shuffle(inner_word)1606... return m.group(1) + "".join(inner_word) + m.group(3)1607>>> text = "Professor Abdolmalek, please report your absences promptly."1608>>> re.sub("(\w)(\w+)(\w)", repl, text)1609'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'1610>>> re.sub("(\w)(\w+)(\w)", repl, text)1611'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'1612```16131614### Поиск всех наречий16151616[`findall()`](https://python-all.ru/3.0/library/re.html#re.findall) находит *все* вхождения шаблона, а не только первое, как [`search()`](https://python-all.ru/3.0/library/re.html#re.search). Например, если бы писателю потребовалось найти все наречия в тексте, он или она могли бы использовать [`findall()`](https://python-all.ru/3.0/library/re.html#re.findall) следующим образом:16171618```python1619>>> text = "He was carefully disguised but captured quickly by police."1620>>> re.findall(r"\w+ly", text)1621['carefully', 'quickly']1622```16231624### Поиск всех наречий и их позиций16251626Если требуется больше информации о всех совпадениях шаблона, чем просто совпавший текст, полезна функция [`finditer()`](https://python-all.ru/3.0/library/re.html#re.finditer), так как она возвращает экземпляры `MatchObject`, а не строки. Продолжая предыдущий пример, если бы писатель хотел найти все наречия *и их позиции* в некотором тексте, он или она мог бы использовать [`finditer()`](https://python-all.ru/3.0/library/re.html#re.finditer) следующим образом:16271628```python1629>>> text = "He was carefully disguised but captured quickly by police."1630>>> for m in re.finditer(r"\w+ly", text):1631... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))163207-16: carefully163340-47: quickly1634```16351636### Нотация сырых строк16371638Сырые строки (`r"text"`) делают регулярные выражения читаемыми. Без них каждый обратный слеш (`'\'`) в регулярном выражении пришлось бы экранировать дополнительным слешем. Например, следующие две строки кода функционально идентичны:16391640```python1641>>> re.match(r"\W(.)\1\W", " ff ")1642<_sre.SRE_Match object at ...>1643>>> re.match("\\W(.)\\1\\W", " ff ")1644<_sre.SRE_Match object at ...>1645```16461647Если требуется сопоставить литеральный обратный слеш, его необходимо экранировать в регулярном выражении. В сырых строках это означает `r"\\"`. Без сырых строк придётся использовать `"\\\\"`, поэтому следующие строки кода функционально идентичны:16481649```python1650>>> re.match(r"\\", r"\\")1651<_sre.SRE_Match object at ...>1652>>> re.match("\\\\", r"\\")1653<_sre.SRE_Match object at ...>1654```1655