Spec-Zone.ru › Python 2.7

re — Операции с регулярными выражениями

Этот модуль предоставляет операции сопоставления регулярных выражений, аналогичные тем, что встречаются в Perl. И шаблоны, и строки, которые должны быть проверены, могут быть строками Unicode, а также строками 8-битного кодирования.

В регулярных выражениях используется символ обратного слэша ('\') для обозначения специальных форм или для использования специальных символов без вызова их специального значения. Это конфликтует с использованием Python того же символа для той же цели в строковых литералах; например, для сопоставления буквального обратного слэша, можно использовать '\\\\' в качестве строки шаблона, потому что регулярное выражение должно быть \\, а каждый обратный слэш должен быть выражен как \\ внутри обычной строки Python.

Решение заключается в использовании синтаксиса необработанных строк Python для шаблонов регулярных выражений; обратные слэши не обрабатываются особым образом в строковых литералах, начинающихся с 'r'. Таким образом, r"\n" — это строка из двух символов, содержащая '\' и 'n', в то время как "\n" — это строка из одного символа, содержащая новую строку. Обычно шаблоны выражаются в коде Python с использованием этого синтаксиса необработанных строк.

Важно отметить, что большинство операций с регулярными выражениями доступны как функции уровня модуля и методы RegexObject. Функции являются сокращениями, которые не требуют предварительного компилирования объекта regex, но пропускают некоторые параметры тонкой настройки.

См. также

Модуль сторонних разработчиков regex, который имеет API, совместимый со стандартной библиотекой re модулем, но предлагает дополнительную функциональность и более полную поддержку Unicode.

1. Синтаксис регулярных выражений

Регулярное выражение (или RE) задает набор строк, которые ему соответствуют; функции в этом модуле позволяют проверить, соответствует ли определённая строка заданному регулярному выражению (или соответствует ли заданное регулярное выражение определённой строке, что сводится к одному и тому же).

Регулярные выражения могут быть конкатенированы для формирования новых регулярных выражений; если A и B — оба регулярных выражения, то AB также является регулярным выражением. В общем случае, если строка p соответствует A, а другая строка q соответствует B, строка pq будет соответствовать AB. Это справедливо, если A или B не содержат операций низкого приоритета; граничные условия между A и B; или имеют ссылки на группы с номерами. Таким образом, сложные выражения легко конструируются из более простых примитивных выражений, описанных здесь. Для получения подробной информации о теории и реализации регулярных выражений см. книгу Фридла, упомянутую выше, или любую другую книгу по построению компиляторов.

Далее следует краткое объяснение формата регулярных выражений. Для получения дополнительной информации и более понятного изложения см. Руководство по регулярным выражениям.

Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, таких как 'A', 'a', или '0', являются простейшими регулярными выражениями; они просто соответствуют сами себе. Вы можете конкатенировать обычные символы, так что last соответствует строке 'last'. (В остальной части этого раздела мы будем писать RE в this special style, обычно без кавычек, и строки для сопоставления 'in single quotes'.)

Некоторые символы, такие как '|' или '(', являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на то, как интерпретируются регулярные выражения вокруг них. Строки шаблонов регулярных выражений не могут содержать нулевые байты, но могут указать нулевой байт, используя обозначение \number, например, '\x00'.

Квалификаторы повторений (*, +, ?, {m,n}, и т.д.) не могут быть непосредственно вложены. Это предотвращает неоднозначность с модификатором "нежадный" суффиксом ?, а также с другими модификаторами в других реализациях. Для применения второго повторения к внутреннему повторению могут быть использованы скобки. Например, выражение (?:a{6})* соответствует любому целому числу кратному шести 'a' символов.

Специальные символы:

'.'

(Точка.) В режиме по умолчанию, это соответствует любому символу, кроме новой строки. Если флаг DOTALL был указан, это соответствует любому символу, включая новую строку.

'^'

(Знак каретки.) Соответствует началу строки, и в режиме MULTILINE также соответствует сразу после каждой новой строки.

'$'

Соответствует концу строки или непосредственно перед новой строкой в конце строки, и в режиме MULTILINE также соответствует перед новой строкой. foo соответствует как ‘foo’, так и ‘foobar’, в то время как регулярное выражение foo$ соответствует только ‘foo’. Более интересно, поиск foo.$ в 'foo1\nfoo2\n' соответствует ‘foo2’ в обычном режиме, но ‘foo1’ в режиме MULTILINE; поиск одного $ в 'foo\n' найдет два (пустых) соответствия: одно непосредственно перед новой строкой и одно в конце строки.

'*'

Заставляет результирующее регулярное выражение соответствовать 0 или более повторениям предшествующего регулярного выражения, столько повторений, сколько возможно. ab* будет соответствовать ‘a’, ‘ab’ или ‘a’, за которым следует любое количество ‘b’.

'+'

Заставляет результирующее регулярное выражение соответствовать 1 или более повторениям предшествующего регулярного выражения. ab+ будет соответствовать ‘a’, за которым следует любое ненулевое количество ‘b’ ; оно не будет соответствовать просто ‘a’.

'?'

Заставляет результирующее регулярное выражение соответствовать 0 или 1 повторению предшествующего регулярного выражения. ab? будет соответствовать либо ‘a’, либо ‘ab’.

*?, +?, ??

Квалификаторы '*', '+', и '?' являются жадными; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если регулярное выражение <.*> соответствует <a> b <c>, оно будет соответствовать всей строке, а не только <a>. Добавление ? после квалификатора заставляет его выполнять соответствие в не-жадном или минимальном режиме; будет соответствовать как можно меньше символов. Использование регулярного выражения <.*?> будет соответствовать только <a>.

{m}

Указывает, что должно быть найдено ровно m копий предыдущего регулярного выражения; меньшее количество соответствий приводит к тому, что все регулярное выражение не соответствует. Например, a{6} будет соответствовать ровно шести символам 'a', но не пяти.

{m,n}

Заставляет результирующее регулярное выражение соответствовать от m до n повторений предшествующего регулярного выражения, пытаясь сопоставить как можно больше повторений. Например, a{3,5} будет соответствовать от 3 до 5 символов 'a'. Пропуск m задает нижнюю границу в ноль, а пропуск n задаёт бесконечную верхнюю границу. Например, a{4,}b будет соответствовать aaaab или тысяче символов 'a', за которыми следует b, но не aaab. Запятая не может быть опущена, иначе модификатор будет смешан с ранее описанной формой.

{m,n}?

Заставляет результирующее регулярное выражение соответствовать от m до n повторений предшествующего регулярного выражения, пытаясь сопоставить как можно меньше повторений. Это не-жадная версия предыдущего квалификатора. Например, в строке из 6 символов 'aaaaaa', a{3,5} будет соответствовать 5 символам 'a', а a{3,5}? будет соответствовать только 3 символам.

'\'

Либо экранирует специальные символы (позволяя вам соответствовать символам, таким как '*', '?', и так далее), либо указывает специальную последовательность; специальные последовательности обсуждаются ниже.

Если вы не используете строку-сырец для выражения шаблона, помните, что Python также использует обратную косую черту в качестве escape-последовательности в строковых литералах; если escape-последовательность не распознаётся анализатором Python, обратная косая черта и последующий символ включаются в результирующую строку. Однако, если Python распознает полученную последовательность, обратную косую черту следует повторять дважды. Это сложно и трудно понять, поэтому настоятельно рекомендуется использовать строковые литералы-сырцы для всех выражений, кроме самых простых.

[]

Используется для указания набора символов. В наборе:

  • Символы могут быть перечислены по отдельности, например, [amk] будет соответствовать 'a', 'm', или 'k'.
  • Диапазоны символов могут быть указаны, указав два символа и разделив их запятой, например, [a-z] будет соответствовать любой строчной букве ASCII, [0-5][0-9] будет соответствовать всем двузначным числам от 00 до 59, а [0-9A-Fa-f] будет соответствовать любой шестнадцатеричной цифре. Если - экранирована (например, [a\-z]) или если она расположена в качестве первого или последнего символа (например, [a-] ), она будет соответствовать буквально '-'.
  • Специальные символы теряют свое специальное значение внутри наборов. Например, [(+*)] будет соответствовать любому из буквальных символов '(', '+', '*', или ')'.
  • Классы символов, такие как \w или \S (определены ниже), также принимаются внутри набора, хотя символы, которым они соответствуют, зависят от того, включен ли режим LOCALE или UNICODE.
  • Символы, которые не находятся в диапазоне, могут быть сопоставлены путем дополнения набора. Если первым символом набора является '^', будут сопоставлены все символы, не входящие в набор. Например, [^5] будет соответствовать любому символу, кроме '5', и [^^] будет соответствовать любому символу, кроме '^'. ^ не имеет специального значения, если это не первый символ в наборе.
  • Чтобы сопоставить буквальный ']' внутри набора, предваряйте его обратной косой чертой или поместите его в начало набора. Например, оба [()[\]{}] и []()[{}] будут соответствовать скобке.
'|'

A|B, где A и B могут быть произвольными регулярными выражениями, создаёт регулярное выражение, которое будет соответствовать либо A, либо B. Произвольное количество регулярных выражений может быть разделено '|' таким образом. Это можно использовать и внутри групп (см. ниже). По мере сканирования целевой строки регулярные выражения, разделённые '|', пробуются слева направо. Когда один шаблон полностью соответствует, эта ветвь принимается. Это означает, что как только A соответствует, B больше не будет проверяться, даже если бы он дал более длинное соответствие в целом. Другими словами, оператор '|' никогда не является жадным. Чтобы сопоставить буквенный символ '|', используйте \|, или заключите его в набор символов, как в [|].

(...)

Сопоставляет любое регулярное выражение внутри скобок и указывает начало и конец группы; содержимое группы может быть получено после выполнения соответствия и может быть сопоставлено позже в строке с помощью специальной последовательности \number, описанной ниже. Чтобы сопоставить литералы '(' или ')', используйте \( или \), или заключите их в набор символов: [(] [)].

(?...)

Это расширение обозначений ('?' после '(' не имеет смысла в противном случае). Первый символ после '?' определяет смысл и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу; (?P<name>...) — единственное исключение из этого правила. Ниже приведены поддерживаемые в настоящее время расширения.

(?iLmsux)

(Одна или несколько букв из набора 'i', 'L', 'm', 's', 'u', 'x'.) Группа соответствует пустой строке; буквы устанавливают соответствующие флаги: re.I (игнорировать регистр), re.L (зависимость от локали), re.M (многострочный), re.S (точка соответствует всем), re.U (зависимость от Юникода) и re.X (развернутый) для всего регулярного выражения. (Флаги описаны в Содержимое модуля.) Это полезно, если вы хотите включить флаги в состав регулярного выражения, а не передавать аргумент флаг функции re.compile().

Обратите внимание, что флаг (?x) изменяет способ обработки выражения. Он должен использоваться в начале строки выражения или после одного или нескольких пробелов. Если перед флагом есть символы, отличные от пробела, результаты не определены.

(?:...)

Незахватывающая версия обычных скобок. Сопоставляет любое регулярное выражение внутри скобок, но подстрока, сопоставленная группой, не может быть извлечена после выполнения соответствия или ссылаться на неё позднее в шаблоне.

(?P<name>...)

Аналогично обычным скобкам, но подстрока, соответствующая группе, доступна через символическое имя группы name. Имена групп должны быть допустимыми идентификаторами Python, и каждое имя группы должно быть определено только один раз в регулярном выражении. Символическая группа также является пронумерованной группой, так же, как если бы группа не имела имени.

Имена групп могут быть использованы в трёх контекстах. Если шаблон (?P<quote>['"]).*?(?P=quote) (т.е. соответствует строке, заключённой в одинарные или двойные кавычки):

Контекст ссылки на группу «quote»

Способы ссылки на неё

в самом шаблоне

  • (?P=quote) (как показано)
  • \1

при обработке объекта совпадения m

  • m.group('quote')
  • m.end('quote') (и т.д.)

в строке, переданной в аргумент repl функции re.sub()

  • \g<quote>
  • \g<1>
  • \1
(?P=name)

Ссылка на именованную группу; она соответствует той части текста, которая была сопоставлена с ранее именованной группой name.

(?#...)

Комментарий; содержимое скобок просто игнорируется.

(?=...)

Сопоставляет, если ... соответствует следующему, но не потребляет никакой части строки. Это называется утверждением «вперед». Например, Isaac (?=Asimov) будет соответствовать 'Isaac ' только в том случае, если за ним следует 'Asimov'.

(?!...)

Сопоставляет, если ... не соответствует следующему. Это утверждение «отрицательное вперед». Например, Isaac (?!Asimov) будет соответствовать 'Isaac ' только в том случае, если за ним не следует 'Asimov'.

(?<=...)

Сопоставляет, если текущая позиция в строке предшествует совпадению с ..., заканчивающемуся в текущей позиции. Это называется утверждением «положительный взгляд назад». (?<=abc)def найдёт совпадение в abcdef, так как взгляд назад продвинется на 3 символа и проверит, соответствует ли содержащийся шаблон. Содержащийся шаблон должен соответствовать строкам некоторой фиксированной длины, что означает, что abc или a|b разрешены, но a* и a{3,4} нет. Ссылки на группы не поддерживаются, даже если они соответствуют строкам некоторой фиксированной длины. Обратите внимание, что шаблоны, начинающиеся с утверждений «положительный взгляд назад», не будут соответствовать в начале искомой строки; вы, скорее всего, захотите использовать функцию search(), а не функцию match():

>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'

Этот пример ищет слово, следующее за дефисом:

>>> m = re.search('(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'
(?<!...)

Сопоставляет, если текущая позиция в строке не предшествует совпадению с .... Это называется утверждением «отрицательный взгляд назад». Аналогично утверждениям «положительный взгляд назад», содержащийся шаблон должен соответствовать строкам некоторой фиксированной длины и не должен содержать ссылок на группы. Шаблоны, начинающиеся с утверждений «отрицательный взгляд назад», могут соответствовать в начале искомой строки.

(?(id/name)yes-pattern|no-pattern)

Попытается сопоставить с yes-pattern , если группа с заданным id или name существует, и с no-pattern , если она не существует. no-pattern является необязательным и может быть опущено. Например, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>) — это плохой шаблон для сопоставления адресов электронной почты, который будет соответствовать '<user@host.com>' и 'user@host.com', но не '<user@host.com'.

Новое в версии 2.4.

Специальные последовательности состоят из '\' и символа из приведенного ниже списка. Если обычный символ не находится в списке, то результирующее регулярное выражение будет соответствовать второму символу. Например, \$ соответствует символу '$'.

\number

Соответствует содержимому группы с тем же номером. Группы нумеруются, начиная с 1. Например, (.+) \1 соответствует 'the the' или '55 55', но не 'thethe' (обратите внимание на пробел после группы). Эта специальная последовательность может быть использована только для соответствия одной из первых 99 групп. Если первая цифра number равна 0, или number состоит из 3 восьмеричных цифр, то это не будет интерпретироваться как совпадение группы, а как символ с восьмеричным значением number. Внутри '[' и ']' класса символов все числовые экранирования обрабатываются как символы.

\A

Сопоставляет только в начале строки.

\b

Сопоставляет пустую строку, но только в начале или конце слова. Слово определяется как последовательность буквенно-цифровых символов или символа подчёркивания, поэтому конец слова обозначается пробелом или символом, не являющимся буквенно-цифровым или символом подчёркивания. Обратите внимание, что формально \b определен как граница между \w и \W символами (или наоборот), или между \w и началом/концом строки, поэтому точный набор символов, считающихся буквенно-цифровыми, зависит от значений флагов UNICODE и LOCALE. Например, r'\bfoo\b' соответствует 'foo', 'foo.', '(foo)', 'bar foo baz', но не 'foobar' или 'foo3'. В диапазоне символов \b представляет символ «вставить» для совместимости с литералами строк Python.

\B

Сопоставляет пустую строку, но только когда она не находится в начале или конце слова. Это означает, что r'py\B' соответствует 'python', 'py3', 'py2', но не 'py', 'py.', или 'py!'. \B — это просто противоположность \b, поэтому также зависит от настроек флагов LOCALE и UNICODE.

\d

При отсутствии флага UNICODE, соответствует любой десятичной цифре; это эквивалентно набору [0-9]. С флагом UNICODE он будет соответствовать тому, что классифицируется как десятичная цифра в базе данных свойств символов Юникода.

\D

При отсутствии флага UNICODE, соответствует любому символу, не являющемуся цифрой; это эквивалентно набору [^0-9]. С флагом UNICODE он будет соответствовать любому символу, кроме символа, помеченного как цифра в базе данных свойств символов Юникода.

\s

При отсутствии флага UNICODE, соответствует любому символу пробела; это эквивалентно набору [ \t\n\r\f\v]. Флаг LOCALE не оказывает дополнительного влияния на соответствие пробелу. Если установлен флаг UNICODE, это будет соответствовать символам [ \t\n\r\f\v] плюс всем символам, классифицируемым как пробел в базе данных свойств символов Юникода.

\S

При отсутствии флага UNICODE, соответствует любому символу, не являющемуся пробелом; это эквивалентно набору [^ \t\n\r\f\v]. Флаг LOCALE не оказывает дополнительного влияния на соответствие не-пробелу. Если установлен флаг UNICODE, то соответствует любому символу, не помеченному как пробел в базе данных свойств символов Юникода.

\w

При отсутствии флагов LOCALE и UNICODE, соответствует любому буквенно-цифровому символу и символу подчёркивания; это эквивалентно набору [a-zA-Z0-9_]. С флагом LOCALE он будет соответствовать набору [0-9_] плюс символам, определённым как буквенно-цифровые для текущей локали. Если установлен флаг UNICODE, это будет соответствовать символам [0-9_] плюс символам, классифицированным как буквенно-цифровые в базе данных свойств символов Юникода.

\W

При отсутствии флагов LOCALE и UNICODE, соответствует любому символу, не являющемуся буквенно-цифровым; это эквивалентно набору [^a-zA-Z0-9_]. С флагом LOCALE он будет соответствовать любому символу, не входящему в набор [0-9_], и не определённому как буквенно-цифровой для текущей локали. Если установлен флаг UNICODE, это будет соответствовать любому символу, не являющемуся [0-9_] плюс символам, классифицированным как не-буквенно-цифровые в базе данных свойств символов Юникода.

\Z

Сопоставляет только в конце строки.

Если оба флага LOCALE и UNICODE включены для определённой последовательности, то флаг LOCALE вступает в силу первым, а затем флаг UNICODE.

Большинство стандартных экранирований, поддерживаемых литералами строк Python, также принимаются парсером регулярных выражений:

\a      \b      \f      \n
\r      \t      \v      \x
\\

(Обратите внимание, что \b используется для представления границ слов и означает «обратный пробел» только внутри символьных классов.)

Восьмеричные экранирования включены в ограниченной форме: если первая цифра — 0, или если есть три восьмеричные цифры, это считается восьмеричным экранированием. В противном случае это ссылка на группу. Как и в случае с литералами строк, восьмеричные экранирования всегда имеют длину не более трёх цифр.

См. также

Mastering Regular Expressions

Книга о регулярных выражениях Джеффри Фридла, опубликованная издательством O’Reilly. Второе издание книги больше не охватывает Python, но первое издание подробно рассказывало о написании хороших шаблонов регулярных выражений.

2. Содержимое модуля

Модуль определяет несколько функций, констант и исключение. Некоторые функции являются упрощёнными версиями полных методов для скомпилированных регулярных выражений. Большинство нетривиальных приложений всегда используют скомпилированную форму.

re.compile(pattern, flags=0)

Компилирует шаблон регулярного выражения в объект регулярного выражения, который можно использовать для сопоставления с помощью его методов match() и search(), описанных ниже.

Поведение выражения можно изменить, указав значение flags. Значения могут быть любыми из следующих переменных, объединённых с помощью побитового ИЛИ (оператора |).

Последовательность

prog = re.compile(pattern)
result = prog.match(string)

эквивалентна

result = re.match(pattern, string)

но использование re.compile() и сохранение полученного объекта регулярного выражения для повторного использования более эффективно, когда выражение будет использоваться несколько раз в одной программе.

Примечание

Скомпилированные версии последних шаблонов, переданных в re.match(), re.search() или re.compile(), кэшируются, поэтому программам, которые используют лишь несколько регулярных выражений за раз, не нужно беспокоиться о компиляции регулярных выражений.

re.DEBUG

Отображает отладочную информацию о скомпилированном выражении.

re.I
re.IGNORECASE

Выполняет сопоставление без учёта регистра; выражения, подобные [A-Z] также будут соответствовать строчным буквам. Это не зависит от текущей локали. Чтобы добиться этого эффекта для не-ASCII-символов Юникода, таких как ü и Ü, добавьте флаг UNICODE.

re.L
re.LOCALE

Делает \w, \W, \b, \B, \s и \S зависимыми от текущей локали.

re.M
re.MULTILINE

При указании символ шаблона '^' соответствует началу строки и началу каждой строки (непосредственно после каждой новой строки); и символ шаблона '$' соответствует концу строки и концу каждой строки (непосредственно перед каждой новой строкой). По умолчанию '^' соответствует только началу строки, а '$' только концу строки и непосредственно перед новой строкой (если таковая имеется) в конце строки.

re.S
re.DOTALL

Делает символ '.' специальным символом, чтобы он соответствовал любому символу вообще, включая новую строку; без этого флага '.' будет соответствовать чему угодно, кроме новой строки.

re.U
re.UNICODE

Делает \w, \W, \b, \B, \d, \D, \s и \S последовательности зависимыми от базы данных свойств символов Юникода. Также включает сопоставление с не-ASCII для IGNORECASE.

Новое в версии 2.0.

re.X
re.VERBOSE

Этот флаг позволяет писать более читабельные регулярные выражения, позволяя визуально отделять логические части шаблона и добавлять комментарии. Пробелы внутри шаблона игнорируются, за исключением случаев, когда они находятся в символьных классах или когда им предшествует экранированный обратный слэш, или внутри токенов, таких как *?, (?: или (?P<...>. Когда строка содержит #, которое не находится в символьном классе и ему не предшествует экранированный обратный слэш, все символы от самого левого такого # до конца строки игнорируются.

Это означает, что два следующих объекта регулярных выражений, которые соответствуют десятичному числу, функционально равны:

a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")
re.search(pattern, string, flags=0)

Ищет в строке первое место, где регулярное выражение шаблон даёт совпадение, и возвращает соответствующий экземпляр MatchObject. Возвращает None если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в какой-либо точке строки.

re.match(pattern, string, flags=0)

Если ноль или более символов в начале строки соответствуют регулярному выражению шаблон, возвращает соответствующий экземпляр MatchObject. Возвращает None если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.

Обратите внимание, что даже в режиме MULTILINE, re.match() будет соответствовать только началу строки, а не началу каждой строки.

Если нужно найти соответствие где-либо в строке, используйте search() (см. также search() vs. match()).

re.split(pattern, string, maxsplit=0, flags=0)

Разделяет строку по появлениям шаблона. Если в шаблоне используются группы захвата, то текст всех групп в шаблоне также возвращается как часть результирующего списка. Если maxsplit не равно нулю, происходит не более maxsplit разделений, и остаток строки возвращается как последний элемент списка. (Примечание о несовместимости: в исходном выпуске Python 1.5, maxsplit игнорировался. Это было исправлено в более поздних выпусках.)

>>> re.split('\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

Если в разделителе есть группы захвата и он соответствует началу строки, результат начнётся с пустой строки. То же самое относится к концу строки:

>>> re.split('(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

Таким образом, компоненты разделителя всегда находятся на тех же относительных индексах в списке результатов (например, если есть одна группа захвата в разделителе, 0-я, 2-я и так далее).

Обратите внимание, что split никогда не будет разделять строку по пустому совпадению шаблона. Например:

>>> re.split('x*', 'foo')
['foo']
>>> re.split("(?m)^$", "foo\n\nbar\n")
['foo\n\nbar\n']

Изменено в версии 2.7: Добавлен необязательный аргумент flags.

re.findall(pattern, string, flags=0)

Возвращает все неперекрывающиеся совпадения шаблона в строке в виде списка строк. Строка сканируется слева направо, и совпадения возвращаются в порядке обнаружения. Если в шаблоне присутствуют одна или несколько групп, возвращается список групп; это будет список кортежей, если в шаблоне более одной группы. Пустые совпадения включаются в результат.

Примечание

Из-за ограничения текущей реализации символ, следующий за пустым совпадением, не включается в следующее совпадение, поэтому findall(r'^|\w+', 'two words') возвращает ['', 'wo', 'words'] (обратите внимание на пропущенную букву «t»). Это исправлено в Python 3.7.

Новое в версии 1.5.2.

Изменено в версии 2.4: Добавлен необязательный аргумент flags.

re.finditer(pattern, string, flags=0)

Возвращает итератор, возвращающий экземпляры MatchObject для всех неперекрывающихся совпадений RE шаблон в строке. Строка сканируется слева направо, и совпадения возвращаются в порядке обнаружения. Пустые совпадения включаются в результат. См. также примечание о findall().

Новое в версии 2.2.

Изменено в версии 2.4: Добавлен необязательный аргумент flags.

END_OF_DOCUMENT_MARKER
re.sub(pattern, repl, string, count=0, flags=0)

Возвращает строку, полученную заменой всех непересекающихся вхождений шаблона pattern в строке string заменой repl. Если шаблон не найден, возвращается string без изменений. repl может быть строкой или функцией; если это строка, все экранированные обратные косые черты в ней обрабатываются. То есть, \n преобразуется в один символ новой строки, \r — в символ возврата каретки и так далее. Неизвестные экранированные последовательности, такие как \j оставляются без изменений. Обратные ссылки, такие как \6, заменяются подстрокой, соответствующей группе 6 в шаблоне. Например:

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

Если repl является функцией, она вызывается для каждого непересекающегося вхождения шаблона pattern. Функция принимает один аргумент — объект совпадения, и возвращает строку замены. Например:

>>> def dashrepl(matchobj):
...     if matchobj.group(0) == '-': return ' '
...     else: return '-'
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
'pro--gram files'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'

Шаблон может быть строкой или объектом RE.

Необязательный аргумент count — максимальное количество заменяемых вхождений шаблона; count должен быть неотрицательным целым числом. Если он опущен или равен нулю, будут заменены все вхождения. Пустые совпадения с шаблоном заменяются только тогда, когда они не смежны с предыдущим совпадением, поэтому sub('x*', '-', 'abc') возвращает '-a-b-c-'.

В строковых аргументах repl, помимо описанных выше экранированных символов и обратных ссылок, \g<name> будет использовать подстроку, соответствующую группе с именем name, как определено синтаксисом (?P<name>...). \g<number> использует соответствующий номер группы; \g<2> поэтому эквивалентно \2, но не неоднозначно в замене, такой как \g<2>0. \20 будет интерпретировано как ссылка на группу 20, а не как ссылка на группу 2, за которой следует буквальный символ '0'. Обратная ссылка \g<0> заменяет всю подстроку, соответствующую выражению регулярного выражения.

Изменено в версии 2.7: Добавлен необязательный аргумент flags.

re.subn(pattern, repl, string, count=0, flags=0)

Выполняет ту же операцию, что и sub(), но возвращает кортеж (new_string, number_of_subs_made).

Изменено в версии 2.7: Добавлен необязательный аргумент flags.

re.escape(pattern)

Экранирует все символы в pattern, кроме букв и цифр ASCII. Это полезно, если вы хотите сопоставить произвольную строку, которая может содержать метасимволы регулярных выражений. Например:

>>> print re.escape('python.exe')
python\.exe

>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
>>> print '[%s]+' % re.escape(legal_chars)
[abcdefghijklmnopqrstuvwxyz0123456789\!\#\$\%\&\'\*\+\-\.\^\_\`\|\~\:]+

>>> operators = ['+', '-', '*', '/', '**']
>>> print '|'.join(map(re.escape, sorted(operators, reverse=True)))
\/|\-|\+|\*\*|\*
re.purge()

Очистить кэш регулярных выражений.

exception re.error

Исключение, возникающее, когда строка, переданная одной из функций, не является допустимым регулярным выражением (например, она может содержать непарные скобки) или когда при компиляции или поиске совпадений возникает ошибка. Это никогда не является ошибкой, если строка не содержит совпадения с шаблоном.

3. Объекты регулярных выражений

class re.RegexObject

Класс RegexObject поддерживает следующие методы и атрибуты:

search(string[, pos[, endpos]])

Ищет в строке string позицию, где данное регулярное выражение дает совпадение, и возвращает соответствующий объект MatchObject. Возвращает None если в строке нет позиции, соответствующей шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в какой-либо точке строки.

Необязательный второй параметр pos задает индекс в строке, с которого следует начать поиск; по умолчанию он равен 0. Это не полностью эквивалентно срезу строки; символ '^' шаблона соответствует действительно началу строки и позициям сразу после новой строки, но необязательно позиции, с которой начинается поиск.

Необязательный параметр endpos ограничивает область поиска в строке; будет как будто строка имеет длину endpos символов, поэтому будут проверены только символы от pos до endpos - 1 на предмет совпадения. Если endpos меньше pos, совпадение не будет найдено. В противном случае, если rx является скомпилированным объектом регулярного выражения, rx.search(string, 0, 50) эквивалентно rx.search(string[:50], 0).

>>> pattern = re.compile("d")
>>> pattern.search("dog")     # Match at index 0
<_sre.SRE_Match object at ...>
>>> pattern.search("dog", 1)  # No match; search doesn't include the "d"
match(string[, pos[, endpos]])

Если нуль или более символов в начале строки string соответствуют данному регулярному выражению, возвращает соответствующий объект MatchObject. Возвращает None если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.

Необязательные параметры pos и endpos имеют такое же значение, как для метода search().

>>> pattern = re.compile("o")
>>> pattern.match("dog")      # No match as "o" is not at the start of "dog".
>>> pattern.match("dog", 1)   # Match as "o" is the 2nd character of "dog".
<_sre.SRE_Match object at ...>

Если вы хотите найти совпадение где-либо в строке string, используйте search() (см. также search() vs. match()).

split(string, maxsplit=0)

Идентично функции split(), используя скомпилированный шаблон.

findall(string[, pos[, endpos]])

Аналогично функции findall(), используя скомпилированный шаблон, но также принимает необязательные параметры pos и endpos, которые ограничивают область поиска, как для match().

finditer(string[, pos[, endpos]])

Аналогично функции finditer(), используя скомпилированный шаблон, но также принимает необязательные параметры pos и endpos, которые ограничивают область поиска, как для match().

sub(repl, string, count=0)

Идентично функции sub(), используя скомпилированный шаблон.

subn(repl, string, count=0)

Идентично функции subn(), используя скомпилированный шаблон.

flags

Флаги сопоставления регулярных выражений. Это комбинация флагов, переданных compile(), и любых (?...) встроенных флагов в шаблоне.

groups

Количество захватывающих групп в шаблоне.

groupindex

Словарь, сопоставляющий имена символьных групп, определенные (?P<id>) с номерами групп. Словарь пуст, если в шаблоне не использовались символьные группы.

pattern

Строка шаблона, из которой был скомпилирован объект RE.

4. Объекты совпадений

class re.MatchObject

Объекты совпадения всегда имеют булево значение True. Поскольку match() и search() возвращают None при отсутствии совпадения, вы можете проверить, было ли совпадение, с помощью простого оператора if:

match = re.search(pattern, string)
if match:
    process(match)

Объекты совпадения поддерживают следующие методы и атрибуты:

expand(template)

Возвращает строку, полученную путем подстановки обратных слэшей в шаблонную строку template, как это делает метод sub(). Экранированные символы, такие как \n, преобразуются в соответствующие символы, а числовые ссылки обратной связи (\1, \2) и именованные ссылки обратной связи (\g<1>, \g<name>) заменяются содержимым соответствующей группы.

group([group1, ...])

Возвращает одну или несколько подгрупп совпадения. Если есть один аргумент, результат — одна строка; если есть несколько аргументов, результат — кортеж с одним элементом на каждый аргумент. Без аргументов group1 по умолчанию равен нулю (возвращается всё совпадение). Если аргумент groupN равен нулю, соответствующее возвращаемое значение — вся строка совпадения; если он находится в диапазоне [1..99], это строка, соответствующая соответствующей скобкой группе. Если номер группы отрицательный или больше, чем количество групп, определённых в шаблоне, генерируется исключение IndexError. Если группа содержится в части шаблона, которая не совпала, соответствующий результат — None. Если группа содержится в части шаблона, которая совпала несколько раз, возвращается последнее совпадение.

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)       # The entire match
'Isaac Newton'
>>> m.group(1)       # The first parenthesized subgroup.
'Isaac'
>>> m.group(2)       # The second parenthesized subgroup.
'Newton'
>>> m.group(1, 2)    # Multiple arguments give us a tuple.
('Isaac', 'Newton')

Если регулярное выражение использует синтаксис (?P<name>...), аргументы groupN также могут быть строками, идентифицирующими группы по их имени. Если строковый аргумент не используется в качестве имени группы в шаблоне, генерируется исключение IndexError.

Довольно сложный пример:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.group('first_name')
'Malcolm'
>>> m.group('last_name')
'Reynolds'

Именованные группы также можно ссылаться по их индексу:

>>> m.group(1)
'Malcolm'
>>> m.group(2)
'Reynolds'

Если группа совпадает несколько раз, доступен только последний результат совпадения:

>>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
>>> m.group(1)                        # Returns only the last match.
'c3'
groups([default])

Возвращает кортеж, содержащий все подгруппы совпадения, начиная с 1 до количества групп в шаблоне. Аргумент default используется для групп, не участвовавших в совпадении; по умолчанию он равен None. (Примечание о несовместимости: в исходном выпуске Python 1.5, если кортеж состоял из одного элемента, возвращалась строка. В более поздних версиях (начиная с 1.5.1) возвращается кортеж из одного элемента.)

Например:

>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
>>> m.groups()
('24', '1632')

Если десятичная точка и всё после неё являются необязательными, не все группы могут участвовать в совпадении. Эти группы будут иметь значение по умолчанию None, если не указан аргумент default:

>>> m = re.match(r"(\d+)\.?(\d+)?", "24")
>>> m.groups()      # Second group defaults to None.
('24', None)
>>> m.groups('0')   # Now, the second group defaults to '0'.
('24', '0')
groupdict([default])

Возвращает словарь, содержащий все именованные подгруппы совпадения, ключи которых — имена подгрупп. Аргумент default используется для групп, не участвовавших в совпадении; по умолчанию он равен None. Например:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.groupdict()
{'first_name': 'Malcolm', 'last_name': 'Reynolds'}
start([group])
end([group])

Возвращает индексы начала и конца подстроки, соответствующей group; group по умолчанию равен нулю (вся сопоставленная подстрока). Возвращает -1 если group существует, но не участвовал в совпадении. Для объекта совпадения m и группы g, участвовавшей в совпадении, подстрока, соответствующая группе g (равносильна m.group(g)), равна

m.string[m.start(g):m.end(g)]

Обратите внимание, что 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.

Пример, удаляющий remove_this из адресов электронной почты:

>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'
span([group])

Для MatchObject m возвращает 2-кортеж (m.start(group), m.end(group)). Обратите внимание, что если group не участвовал в совпадении, это (-1, -1). group по умолчанию равен нулю, всё совпадение.

pos

Значение pos, которое было передано методу search() или match() объекта RegexObject. Это индекс в строке, с которого движок RE начал поиск совпадения.

endpos

Значение endpos, которое было передано методу search() или match() объекта RegexObject. Это индекс в строке после которого движок RE не будет искать совпадение.

lastindex

Целочисленный индекс последней сопоставленной захватывающей группы или None если вообще не было сопоставленной группы. Например, выражения (a)b, ((a)(b)), и ((ab)) будут иметь значение lastindex == 1 при применении к строке 'ab', в то время как выражение (a)(b) будет иметь значение lastindex == 2, если применено к той же строке.

lastgroup

Имя последней сопоставленной захватывающей группы, или None если у группы нет имени, или если вообще не было сопоставленной группы.

re

Объект регулярного выражения, метод match() или search() которого создал этот экземпляр MatchObject.

string

Строка, переданная методам match() или search().

5. Примеры

5.1. Проверка на пару

В этом примере мы используем следующую вспомогательную функцию для более красивого отображения объектов совпадения:

def displaymatch(match):
    if match is None:
        return None
    return '<Match: %r, groups=%r>' % (match.group(), match.groups())

Предположим, вы пишете программу для покера, где рука игрока представлена строкой из 5 символов, каждый из которых представляет карту: «a» для туза, «k» для короля, «q» для дамы, «j» для валета, «t» для десятки, а «2» до «9» представляют карту с этим значением.

Чтобы проверить, является ли данная строка валидной рукой, можно сделать следующее:

>>> valid = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid.match("akt5q"))  # Valid.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid.match("akt5e"))  # Invalid.
>>> displaymatch(valid.match("akt"))    # Invalid.
>>> displaymatch(valid.match("727ak"))  # Valid.
"<Match: '727ak', groups=()>"

Последняя рука, "727ak", содержала пару или две карты с одинаковым значением. Для соответствия этому с регулярным выражением можно использовать ссылки обратной связи следующим образом:

>>> pair = re.compile(r".*(.).*\1")
>>> displaymatch(pair.match("717ak"))     # Pair of 7s.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair.match("718ak"))     # No pairs.
>>> displaymatch(pair.match("354aa"))     # Pair of aces.
"<Match: '354aa', groups=('a',)>"

Чтобы узнать, какая карта составляет пару, можно использовать метод group() объекта MatchObject следующим образом:

>>> pair.match("717ak").group(1)
'7'

# Error because re.match() returns None, which doesn't have a group() method:
>>> pair.match("718ak").group(1)
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    re.match(r".*(.).*\1", "718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'

>>> pair.match("354aa").group(1)
'a'

5.2. Моделирование scanf()

В настоящее время в Python нет эквивалента scanf(). Регулярные выражения обычно более мощные, хотя и более громоздкие, чем форматирующие строки scanf(). Таблица ниже предлагает более или менее эквивалентные сопоставления между маркерами форматирования scanf() и регулярными выражениями.

scanf() Маркер

Регулярное выражение

%c

.

%5c

.{5}

%d

[-+]?\d+

%e, %E, %f, %g

[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?

%i

[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)

%o

[-+]?[0-7]+

%s

\S+

%u

\d+

%x, %X

[-+]?(0[xX])?[\dA-Fa-f]+

Для извлечения имени файла и чисел из строки, такой как

/usr/sbin/sendmail - 0 errors, 4 warnings

вы бы использовали форматирование scanf()

%s - %d errors, %d warnings

Эквивалентное регулярное выражение было бы

(\S+) - (\d+) errors, (\d+) warnings

5.3. search() vs. match()

Python предлагает две разные примитивные операции, основанные на регулярных выражениях: re.match() проверяет соответствие только в начале строки, в то время как re.search() проверяет соответствие где угодно в строке (это то, что Perl делает по умолчанию).

Например:

>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<_sre.SRE_Match object at ...>

Регулярные выражения, начинающиеся с '^' могут использоваться с search() для ограничения соответствия началом строки:

>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<_sre.SRE_Match object at ...>

Однако обратите внимание, что в режиме MULTILINE match() соответствует только началу строки, тогда как использование search() с регулярным выражением, начинающимся с '^' будет соответствовать началу каждой строки.

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<_sre.SRE_Match object at ...>

5.4. Создание справочника

split() разбивает строку на список, ограниченный переданным шаблоном. Этот метод незаменим для преобразования текстовых данных в структуры данных, которые легко читаются и изменяются в Python, как показано в следующем примере, создающем справочник.

Сначала вот входные данные. Обычно они могут поступать из файла, здесь мы используем синтаксис строк с тройными кавычками:

>>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""

Записи разделены одной или несколькими строками новой строки. Теперь мы преобразуем строку в список, где каждая непустая строка имеет свою запись:

>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']

Наконец, разделим каждую запись на список с именем, фамилией, номером телефона и адресом. Мы используем параметр maxsplit метода split(), потому что в адресе есть пробелы, которые входят в наш разделительный шаблон:

>>> [re.split(":? ", entry, 3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]

Шаблон :? соответствует двоеточию после фамилии, чтобы он не появлялся в результирующем списке. С шаблоном maxsplit 4, мы могли бы разделить номер дома и название улицы:

>>> [re.split(":? ", entry, 4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]

5.5. Обработка текста

sub() заменяет каждое вхождение шаблона строкой или результатом функции. Этот пример демонстрирует использование sub() с функцией для «обработки» текста или случайного изменения порядка всех символов в каждом слове предложения, за исключением первого и последнего:

>>> def repl(m):
...     inner_word = list(m.group(2))
...     random.shuffle(inner_word)
...     return m.group(1) + "".join(inner_word) + m.group(3)
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'

5.6. Поиск всех наречий

findall() соответствует всем вхождениям шаблона, а не только первому, как search(). Например, если автор хотел найти все наречия в некотором тексте, он мог бы использовать findall() следующим образом:

>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly", text)
['carefully', 'quickly']

5.7. Поиск всех наречий и их позиций

Если требуется больше информации о всех совпадениях шаблона, чем совпавший текст, finditer() полезен, так как он предоставляет экземпляры MatchObject вместо строк. Продолжая предыдущий пример, если автор хотел найти все наречия и их позиции в некотором тексте, он бы использовал finditer() следующим образом:

>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly", text):
...     print '%02d-%02d: %s' % (m.start(), m.end(), m.group(0))
07-16: carefully
40-47: quickly

5.8. Обозначение «сырых» строк

Обозначение «сырых» строк (r"text") сохраняет регулярные выражения в целостности. Без него каждый обратный слэш ('\') в регулярном выражении должен был бы предваряться еще одним, чтобы экранировать его. Например, две следующие строки кода функционально идентичны:

>>> re.match(r"\W(.)\1\W", " ff ")
<_sre.SRE_Match object at ...>
>>> re.match("\\W(.)\\1\\W", " ff ")
<_sre.SRE_Match object at ...>

Когда нужно сопоставить буквальный обратный слэш, его необходимо экранировать в регулярном выражении. С использованием обозначения «сырых» строк это означает r"\\". Без обозначения «сырых» строк необходимо использовать "\\\\", что делает следующие строки кода функционально идентичными:

>>> re.match(r"\\", r"\\")
<_sre.SRE_Match object at ...>
>>> re.match("\\\\", r"\\")
<_sre.SRE_Match object at ...>

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/re.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API