re — Операции с регулярными выражениями
Исходный код: Lib/re/
Этот модуль предоставляет операции поиска по регулярным выражениям, аналогичные тем, которые используются в Perl.
И шаблоны, и строки для поиска могут быть строками Unicode (str), а также 8-битными строками (bytes). Однако строки Unicode и 8-битные строки нельзя смешивать: то есть нельзя сопоставить строку Unicode с шаблоном bytes или наоборот; аналогично, при запросе замены строка замены должна быть того же типа, что и шаблон и строка поиска.
В регулярных выражениях символ обратной косой черты ('\') используется для обозначения специальных форм или для того, чтобы специальные символы использовались без вызова их особого значения. Это конфликтует с использованием Python того же символа для той же цели в строковых литералах; например, чтобы найти буквальную обратную косую черту, возможно, придётся записать '\\\\' в качестве строки шаблона, поскольку регулярное выражение должно быть \\, а каждая обратная косая черта должна быть представлена как \\ внутри обычного строкового литерала Python. Также обратите внимание: любые недопустимые escape-последовательности при использовании обратной косой черты в строковых литералах Python теперь вызывают предупреждение DeprecationWarning, а в будущем это станет ошибкой SyntaxError. Это произойдёт, даже если такая последовательность допустима в регулярном выражении.
Решение — использовать необработанную строковую нотацию Python для шаблонов регулярных выражений; обратные косые черты не обрабатываются особым образом в строковом литерале с префиксом 'r'. Таким образом, r"\n" — это строка из двух символов, содержащая '\' и 'n', тогда как "\n" — это строка из одного символа, содержащая символ новой строки. Обычно шаблоны в коде Python записываются с использованием этой необработанной строковой нотации.
Важно отметить, что большинство операций с регулярными выражениями доступны в виде функций уровня модуля и методов для скомпилированных регулярных выражений. Функции — это сокращённый способ вызова, при котором не требуется предварительно компилировать объект регулярного выражения, но некоторые параметры тонкой настройки недоступны.
См. также
Сторонний модуль regex, API которого совместим с модулем стандартной библиотеки re, но который предлагает дополнительные возможности и более полную поддержку Unicode.
Синтаксис регулярных выражений
Регулярное выражение (или RE) задаёт набор соответствующих ему строк; функции этого модуля позволяют проверить, соответствует ли заданное регулярное выражение определённой строке (или, что сводится к тому же, соответствует ли определённая строка заданному регулярному выражению).
Регулярные выражения можно объединять в новые регулярные выражения; если A и B — регулярные выражения, то AB также является регулярным выражением. В общем случае, если строка p соответствует A, а другая строка q соответствует B, то строка pq будет соответствовать AB. Это справедливо, если только A или B не содержат операций с низким приоритетом; граничных условий между A и B; или ссылок на группы по номеру. Таким образом, сложные выражения можно легко построить из более простых примитивных выражений, описанных здесь. За подробностями теории и реализации регулярных выражений обращайтесь к книге Фридла [Frie09] или почти к любому учебнику по созданию компиляторов.
Ниже приводится краткое объяснение формата регулярных выражений. Дополнительные сведения и более доступное изложение см. в разделе Руководство по регулярным выражениям.
Регулярные выражения могут содержать специальные и обычные символы. Большинство обычных символов, таких как 'A', 'a' или '0', — это простейшие регулярные выражения; они просто соответствуют самим себе. Обычные символы можно объединять, поэтому last соответствует строке 'last'. (Далее в этом разделе регулярные выражения мы будем записывать в this special style, обычно без кавычек, а строки, которым они должны соответствовать, — в 'in single quotes'.)
Некоторые символы, например '|' или '(', являются специальными. Специальные символы обозначают классы обычных символов или влияют на интерпретацию окружающих их регулярных выражений.
Операторы повторения, или квантификаторы (*, +, ?, {m,n} и т. д.), нельзя непосредственно вкладывать друг в друга. Это позволяет избежать неоднозначности с суффиксом модификатора нежадного сопоставления ? и с другими модификаторами в иных реализациях. Чтобы применить повторение к внутреннему повторению, можно использовать круглые скобки. Например, выражение (?:a{6})* соответствует любому количеству, кратному шести, символов 'a'.
Специальные символы:
-
. -
(Точка.) В режиме по умолчанию соответствует любому символу, кроме перевода строки. Если указан флаг
DOTALL, соответствует любому символу, включая перевод строки.
-
^ -
(Карет.) Соответствует началу строки, а в режиме
MULTILINEтакже соответствует позиции сразу после каждого перевода строки.
-
$ -
Соответствует концу строки или позиции непосредственно перед переводом строки в конце строки, а в режиме
MULTILINEтакже соответствует позиции перед переводом строки.fooсоответствует и ‘foo’, и ‘foobar’, тогда как регулярное выражениеfoo$соответствует только ‘foo’. Более интересный пример: поискfoo.$в'foo1\nfoo2\n'обычно находит ‘foo2’, но в режимеMULTILINEнаходит ‘foo1’; поиск одного$в'foo\n'обнаружит два (пустых) совпадения: одно непосредственно перед переводом строки, а другое в конце строки.
-
* -
Заставляет результирующее регулярное выражение соответствовать 0 или более повторениям предшествующего регулярного выражения — максимально возможному их количеству.
ab*будет соответствовать ‘a’, ‘ab’ или ‘a’, за которым следует любое количество символов ‘b’.
-
+ -
Заставляет результирующее регулярное выражение соответствовать 1 или более повторениям предшествующего регулярного выражения.
ab+будет соответствовать ‘a’, за которым следует ненулевое количество символов ‘b’; одной букве ‘a’ оно не соответствует.
-
? -
Заставляет результирующее регулярное выражение соответствовать 0 или 1 повторению предшествующего регулярного выражения.
ab?будет соответствовать либо ‘a’, либо ‘ab’.
-
*?, +?, ?? -
Квантификаторы
'*','+'и'?'являются жадными: они соответствуют максимально возможному количеству текста. Иногда такое поведение нежелательно; если применить регулярное выражение<.*>к'<a> b <c>', оно будет соответствовать всей строке, а не только'<a>'. Если добавить?после квантификатора, сопоставление станет нежадным или минимальным: будет сопоставлено как можно меньше символов. Регулярное выражение<.*?>будет соответствовать только'<a>'.
-
*+, ++, ?+ -
Как и квантификаторы
'*','+'и'?', квантификаторы с добавленным'+'также соответствуют максимально возможному количеству повторений. Однако, в отличие от обычных жадных квантификаторов, они не допускают возврата при неудачном сопоставлении следующего за ними выражения. Такие квантификаторы называются обладающими жадностью без возврата (possessive). Например,a*aсоответствует'aaaa', потому чтоa*соответствует всем четырём символам'a', но при обнаружении последнего'a'происходит возврат по выражению: в итогеa*соответствует всего трём символам'a', а четвёртый'a'соответствует последнему'a'. Однако при использованииa*+aдля сопоставления с'aaaa'выражениеa*+соответствует всем четырём символам'a', но когда последний'a'не находит дополнительных символов, выражение не может вернуться назад и поэтому сопоставление завершается неудачей.x*+,x++иx?+эквивалентны соответственно(?>x*),(?>x+)и(?>x?).Добавлено в версии 3.11.
-
{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 повторений предшествующего регулярного выражения, пытаясь сопоставить как можно меньше повторений. Это нежадная версия предыдущего квантификатора. Например, для строки
'aaaaaa'длиной 6 символовa{3,5}соответствует 5 символам'a', тогда какa{3,5}?соответствует только 3 символам. -
{m,n}+ -
Заставляет результирующее регулярное выражение соответствовать от m до n повторений предшествующего регулярного выражения, пытаясь сопоставить как можно больше повторений, не устанавливая точек возврата. Это версия приведённого выше квантификатора, обладающая жадностью без возврата. Например, для строки
'aaaaaa'длиной 6 символовa{3,5}+aaпытается сопоставить 5 символов'a', а затем, поскольку требуется ещё 2 символа'a', которым не хватает символов, завершится неудачей; тогда какa{3,5}aaсопоставит строку:a{3,5}захватит 5 символов, затем после возврата будут сопоставлены 4 символа'a', а последние 2 символа'a'будут сопоставлены заключительнымaaв шаблоне.x{m,n}+эквивалентен(?>x{m,n}).Добавлено в версии 3.11.
-
\ -
Либо экранирует специальные символы (что позволяет сопоставлять такие символы, как
'*','?'и т. д.), либо обозначает специальную последовательность; специальные последовательности описаны ниже.Если вы не используете необработанную строку для записи шаблона, помните, что 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]или[a-]), он соответствует буквальному символу'-'. - Специальные символы теряют своё особое значение внутри наборов. Например,
[(+*)]соответствует любому из буквальных символов'(','+','*'или')'.
- Внутри набора также допускаются классы символов, такие как
\wили\S(определённые ниже), хотя соответствующие им символы зависят от используемых флагов.
- Символы, не входящие в диапазон, можно сопоставить, если инвертировать набор. Если первый символ набора —
'^', будут сопоставляться все символы, которые не входят в набор. Например,[^5]соответствует любому символу, кроме'5', а[^^]соответствует любому символу, кроме'^'.^не имеет особого значения, если находится не в начале набора. - Чтобы сопоставить буквальный
']'внутри набора, поставьте перед ним обратную косую черту или поместите его в начало набора. Например, и[()[\]{}], и[]()[{}]соответствуют закрывающей квадратной скобке, а также открывающей квадратной скобке, фигурным и круглым скобкам.
- В будущем может быть добавлена поддержка вложенных наборов и операций над наборами, как в Техническом стандарте Unicode № 18. Это изменило бы синтаксис, поэтому для подготовки к этому изменению пока что в неоднозначных случаях будет выдаваться предупреждение
FutureWarning. К таким случаям относятся наборы, начинающиеся с буквального'['или содержащие буквальные последовательности символов'--','&&','~~'и'||'. Чтобы избежать предупреждения, экранируйте их обратной косой чертой.
Изменено в версии 3.7: Выдаётся
FutureWarning, если набор символов содержит конструкции, семантика которых изменится в будущем. - Символы можно перечислять по отдельности; например,
-
| -
A|B, где A и B могут быть произвольными регулярными выражениями, создаёт регулярное выражение, соответствующее либо A, либо B. Таким образом, с помощью'|'можно разделить любое количество регулярных выражений. Этот оператор также можно использовать внутри групп (см. ниже). При просмотре целевой строки регулярные выражения, разделённые'|', проверяются слева направо. Как только один из шаблонов полностью соответствует строке, эта ветвь принимается. Это означает, что после соответствия A шаблон B больше не проверяется, даже если он обеспечил бы более длинное общее совпадение. Иными словами, оператор'|'никогда не бывает жадным. Чтобы сопоставить буквальный'|', используйте\|или заключите его в класс символов, как в[|].
-
(...) -
Соответствует регулярному выражению внутри круглых скобок и обозначает начало и конец группы; содержимое группы можно получить после выполнения сопоставления, а также сопоставить позднее в строке с помощью специальной последовательности
\number, описанной ниже. Чтобы сопоставить буквальные символы'('или')', используйте\(или\)либо заключите их в класс символов:[(],[)].
-
(?...) -
Это обозначение расширения (
'?'после'('иначе не имеет смысла). Первый символ после'?'определяет значение и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу;(?P<name>...)— единственное исключение из этого правила. Ниже перечислены поддерживаемые в настоящее время расширения. -
(?aiLmsux) -
(Одна или несколько букв из набора
'a','i','L','m','s','u','x'.) Группа соответствует пустой строке; буквы задают соответствующие флаги для всего регулярного выражения:-
re.A(сопоставление только ASCII) -
re.I(без учёта регистра) -
re.L(зависит от локали) -
re.M(многострочный режим) -
re.S(точка соответствует любому символу) -
re.U(сопоставление с учётом Unicode) -
re.X(подробный режим)
(Флаги описаны в разделе Содержимое модуля.) Это удобно, если вы хотите включить флаги в регулярное выражение, а не передавать аргумент flag функции
re.compile(). Флаги должны стоять в начале строки выражения.Изменено в версии 3.11: Эту конструкцию можно использовать только в начале выражения.
-
-
(?:...) -
Вариант обычных круглых скобок, не захватывающий группу. Соответствует регулярному выражению внутри скобок, но подстроку, сопоставленную группой, нельзя получить после сопоставления или использовать в качестве ссылки далее в шаблоне.
-
(?aiLmsux-imsx:...) -
(Ноль или более букв из набора
'a','i','L','m','s','u','x'; необязательно за ними следует'-', после которого указывается одна или несколько букв из набора'i','m','s','x'.) Буквы задают или отменяют соответствующие флаги для части выражения:-
re.A(сопоставление только ASCII) -
re.I(без учёта регистра) -
re.L(зависит от локали) -
re.M(многострочный режим) -
re.S(точка соответствует любому символу) -
re.U(сопоставление с учётом Unicode) -
re.X(подробный режим)
(Флаги описаны в разделе Содержимое модуля.)
Буквы
'a','L'и'u'взаимоисключающие, если используются как встроенные флаги, поэтому их нельзя объединять или ставить после'-'. Вместо этого, если одна из них появляется во встроенной группе, она переопределяет режим сопоставления во внешней группе. В шаблонах Unicode(?a:...)переключает сопоставление в режим только ASCII, а(?u:...)— в режим Unicode (по умолчанию). В шаблонах bytes(?L:...)переключает сопоставление в режим, зависящий от локали, а(?a:...)— в режим только ASCII (по умолчанию). Переопределение действует только внутри небольшой встроенной группы; за её пределами восстанавливается исходный режим сопоставления.Добавлено в версии 3.6.
Изменено в версии 3.7: Буквы
'a','L'и'u'также можно использовать в группе. -
-
(?>...) -
Пытается сопоставить
...как отдельное регулярное выражение и, если это удаётся, продолжает сопоставлять оставшуюся часть шаблона. Если следующая часть шаблона не соответствует строке, стек можно размотать только до точки перед(?>...), поскольку после выхода выражение, называемое атомарной группой, отбрасывает все точки стека внутри себя. Таким образом,(?>.*).никогда ни с чем не совпадёт: сначала.*сопоставит все возможные символы, а затем, поскольку больше не останется символов для сопоставления, заключительный.не найдёт совпадения. Поскольку в атомарной группе не сохранено ни одной точки стека, а перед ней нет точки стека, всё выражение не будет соответствовать строке.Добавлено в версии 3.11.
-
(?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
Устарело с версии 3.11: Имя группы name содержит символы за пределами диапазона ASCII (
b'\x00'-b'\x7f') в шаблонахbytes. -
-
(?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(r'(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'
Изменено в версии 3.5: Добавлена поддержка ссылок на группы фиксированной длины.
-
(?<!...) -
Соответствует строке, если перед текущей позицией нет совпадения с
.... Это называется негативной проверкой предварительного просмотра назад. Как и в случае с положительными проверками предварительного просмотра назад, содержащийся шаблон должен соответствовать строкам только фиксированной длины. Шаблоны, начинающиеся с негативной проверки предварительного просмотра назад, могут соответствовать началу искомой строки.
-
(?(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'и не'user@host.com>'.Устарело с версии 3.11: Идентификатор группы id содержит символы, отличные от цифр ASCII. Имя группы name содержит символы за пределами диапазона ASCII (
b'\x00'-b'\x7f') в строках заменыbytes.
Специальные последовательности состоят из '\' и одного символа из приведённого ниже списка. Если обычный символ не является цифрой или буквой ASCII, результирующее регулярное выражение будет соответствовать этому второму символу. Например, \$ соответствует символу '$'.
-
\number -
Соответствует содержимому группы с тем же номером. Нумерация групп начинается с 1. Например,
(.+) \1соответствует'the the'или'55 55', но не'thethe'(обратите внимание на пробел после группы). Эту специальную последовательность можно использовать только для сопоставления с одной из первых 99 групп. Если первая цифра number равна 0 или number состоит из 3 восьмеричных цифр, последовательность будет интерпретирована не как ссылка на группу, а как символ с восьмеричным значением number. Внутри'['и']'класса символов все числовые escape-последовательности трактуются как символы.
-
\A -
Соответствует только в начале строки.
-
\b -
Соответствует пустой строке, но только в начале или в конце слова. Слово определяется как последовательность символов слова. Формально
\bопределяется как граница между символом\wи символом\W(или наоборот), либо между\wи началом или концом строки. Это означает, чтоr'\bat\b'соответствует'at','at.','(at)'и'as at ay', но не'attempt'или'atlas'.По умолчанию символами слова в шаблонах Unicode (str) являются буквы и цифры Unicode, а также символ подчёркивания; это можно изменить с помощью флага
ASCII. Если используется флагLOCALE, границы слов определяются текущей локалью.Примечание
Внутри диапазона символов
\bобозначает символ возврата на одну позицию (backspace) для совместимости со строковыми литералами Python.
-
\B -
Соответствует пустой строке, но только если она не находится в начале или в конце слова. Это означает, что
r'at\B'соответствует'athens','atom','attorney', но не'at','at.'или'at!'.\Bпротивоположен\b, поэтому символами слова в шаблонах Unicode (str) являются буквы и цифры Unicode или символ подчёркивания, хотя это можно изменить с помощью флагаASCII. Если используется флагLOCALE, границы слов определяются текущей локалью.
-
\d -
- Для шаблонов Unicode (str):
-
Соответствует любой десятичной цифре Unicode (то есть любому символу категории Unicode [Nd]). Сюда входят
[0-9], а также многие другие цифровые символы.При использовании флага
ASCIIсоответствует[0-9]. - Для 8-битных шаблонов (bytes):
-
Соответствует любой десятичной цифре из набора символов ASCII; эквивалентно
[0-9].
-
\D -
Соответствует любому символу, который не является десятичной цифрой. Это противоположность
\d.Соответствует
[^0-9], если используется флагASCII.
-
\s -
- Для шаблонов Unicode (str):
-
Соответствует символам пробельных символов Unicode (в том числе
[ \t\n\r\f\v], а также многим другим символам, например неразрывным пробелам, обязательным по типографским правилам многих языков).Соответствует
[ \t\n\r\f\v], если используется флагASCII. - Для 8-битных шаблонов (bytes):
-
Соответствует символам, которые считаются пробельными в наборе символов ASCII; это эквивалентно
[ \t\n\r\f\v].
-
\S -
Соответствует любому символу, который не является пробельным. Это противоположность
\s.Соответствует
[^ \t\n\r\f\v], если используется флагASCII.
-
\w -
- Для шаблонов Unicode (str):
-
Соответствует символам слова Unicode; сюда входят все буквенно-цифровые символы Unicode (как определено в
str.isalnum()), а также символ подчёркивания (_).Соответствует
[a-zA-Z0-9_], если используется флагASCII. - Для 8-битных шаблонов (bytes):
-
Соответствует символам, которые считаются буквенно-цифровыми в наборе символов ASCII; это эквивалентно
[a-zA-Z0-9_]. Если используется флагLOCALE, соответствует символам, которые считаются буквенно-цифровыми в текущей локали, и символу подчёркивания.
-
\W -
Соответствует любому символу, который не является символом слова. Это противоположность
\w. По умолчанию соответствует символам, отличным от подчёркивания (_), для которыхstr.isalnum()возвращаетFalse.Соответствует
[^a-zA-Z0-9_], если используется флагASCII.Если используется флаг
LOCALE, соответствует символам, которые не являются ни буквенно-цифровыми в текущей локали, ни символом подчёркивания.
-
\Z -
Соответствует только в конце строки.
Большинство стандартных escape-последовательностей, поддерживаемых строковыми литералами Python, также принимаются анализатором регулярных выражений:
\a \b \f \n \N \r \t \u \U \v \x \\
(Обратите внимание, что \b используется для обозначения границ слов и означает «возврат на шаг» только внутри классов символов.)
Escape-последовательности '\u', '\U' и '\N' распознаются только в шаблонах Unicode (str). В шаблонах bytes они приводят к ошибке. Неизвестные escape-последовательности с буквами ASCII зарезервированы для будущего использования и считаются ошибками.
Восьмеричные escape-последовательности поддерживаются в ограниченной форме. Если первая цифра — 0 или указаны три восьмеричные цифры, последовательность считается восьмеричной escape-последовательностью. В противном случае это ссылка на группу. Как и в строковых литералах, длина восьмеричных escape-последовательностей не превышает трёх цифр.
Изменено в версии 3.3: Добавлены escape-последовательности '\u' и '\U'.
Изменено в версии 3.6: Неизвестные escape-последовательности, состоящие из '\' и буквы ASCII, теперь считаются ошибками.
Изменено в версии 3.8: Добавлена escape-последовательность '\N{name}'. Как и в строковых литералах, она раскрывается в именованный символ Unicode (например, '\N{EM DASH}').
Содержимое модуля
Модуль определяет несколько функций, констант и исключение. Некоторые функции являются упрощёнными версиями полнофункциональных методов для скомпилированных регулярных выражений. В большинстве нетривиальных приложений всегда используется скомпилированная форма.
Флаги
Изменено в версии 3.6: Константы флагов теперь являются экземплярами RegexFlag, подкласса enum.IntFlag.
-
class re.RegexFlag -
Класс
enum.IntFlag, содержащий перечисленные ниже параметры регулярных выражений.Добавлено в версии 3.11: — добавлен в
__all__
-
re.A -
re.ASCII -
Заставляет
\w,\W,\b,\B,\d,\D,\sи\Sвыполнять поиск только по ASCII вместо полного поиска по Unicode. Это имеет смысл только для шаблонов Unicode (str) и игнорируется для шаблонов bytes.Соответствует встроенному флагу
(?a).
-
re.DEBUG -
Выводит отладочную информацию о скомпилированном выражении.
Соответствующего встроенного флага нет.
-
re.I -
re.IGNORECASE -
Выполняет поиск без учёта регистра; выражения вроде
[A-Z]также будут соответствовать строчным буквам. Полный поиск с учётом Unicode (например,Üбудет соответствоватьü) также работает, если только флагASCIIне используется для отключения соответствий символам вне ASCII. Текущая локаль не влияет на действие этого флага, если одновременно не используется флагLOCALE.Соответствует встроенному флагу
(?i).Обратите внимание: при использовании шаблонов Unicode
[a-z]или[A-Z]вместе с флагомIGNORECASEим будут соответствовать 52 буквы ASCII и 4 дополнительные буквы вне ASCII: «İ» (U+0130, заглавная латинская I с точкой сверху), «ı» (U+0131, строчная латинская i без точки), «ſ» (U+017F, длинная строчная латинская s) и «K» (U+212A, знак кельвина). Если используется флагASCII, соответствия будут найдены только для букв от «a» до «z» и от «A» до «Z».
-
re.L -
re.LOCALE -
Заставляет
\w,\W,\b,\Bи поиск без учёта регистра зависеть от текущей локали. Этот флаг можно использовать только с шаблонами bytes.Соответствует встроенному флагу
(?L).Предупреждение
Использовать этот флаг не рекомендуется; рассмотрите возможность поиска с учётом Unicode. Механизм локалей крайне ненадёжен, поскольку одновременно обрабатывает только одну «культуру» и работает только с 8-битными локалями. Для шаблонов Unicode (str) поиск с учётом Unicode включён по умолчанию и позволяет работать с разными локалями и языками.
Изменено в версии 3.7: Объекты скомпилированных регулярных выражений с флагом
LOCALEбольше не зависят от локали на момент компиляции. На результат поиска влияет только локаль, действующая во время поиска.
-
re.M -
re.MULTILINE -
Если указан этот флаг, символ шаблона
'^'соответствует началу строки и началу каждой строки (сразу после каждого символа новой строки); а символ шаблона'$'соответствует концу строки и концу каждой строки (непосредственно перед каждым символом новой строки). По умолчанию'^'соответствует только началу строки, а'$'— только концу строки и непосредственно перед символом новой строки (если он есть) в конце строки.Соответствует встроенному флагу
(?m).
-
re.NOFLAG -
Обозначает отсутствие применённых флагов; значение —
0. Этот флаг можно использовать как значение по умолчанию для именованного аргумента функции или как базовое значение, к которому условно применяются побитовым ИЛИ другие флаги. Пример использования в качестве значения по умолчанию:def myfunc(text, flag=re.NOFLAG): return re.match(text, flag)Добавлено в версии 3.11.
-
re.S -
re.DOTALL -
Заставляет специальный символ
'.'соответствовать любому символу, включая символ новой строки; без этого флага'.'соответствует любому символу, кроме символа новой строки.Соответствует встроенному флагу
(?s).
-
re.U -
re.UNICODE -
В Python 3 для шаблонов
strпо умолчанию выполняется поиск с учётом символов Unicode. Поэтому этот флаг избыточен и не оказывает никакого эффекта; он сохранён только для обратной совместимости.См.
ASCII, чтобы ограничить поиск символами ASCII.
-
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*")Соответствует встроенному флагу
(?x).
Функции
-
re.compile(pattern, flags=0) -
Компилирует шаблон регулярного выражения в объект регулярного выражения, который можно использовать для поиска с помощью методов
match(),search()и других методов, описанных ниже.Поведение выражения можно изменить, указав значение flags. В качестве значений можно использовать любые переменные из раздела флаги, объединяя их побитовой операцией ИЛИ (оператор
|).Последовательность
prog = re.compile(pattern) result = prog.match(string)
эквивалентна
result = re.match(pattern, string)
но использование
re.compile()и сохранение полученного объекта регулярного выражения для повторного использования эффективнее, если выражение будет использоваться в программе несколько раз.Примечание
Скомпилированные версии последних шаблонов, переданных в
re.compile()и функции поиска на уровне модуля, кэшируются, поэтому программам, которые одновременно используют лишь несколько регулярных выражений, не нужно беспокоиться об их компиляции.
-
re.search(pattern, string, flags=0) -
Просматривает string в поисках первого места, где регулярное выражение pattern даёт совпадение, и возвращает соответствующий объект
Match. ВозвращаетNone, если в строке нет позиции, соответствующей шаблону; обратите внимание, что это не то же самое, что найти совпадение нулевой длины в некотором месте строки.
-
re.match(pattern, string, flags=0) -
Если ноль или более символов в начале string соответствуют регулярному выражению pattern, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это не то же самое, что совпадение нулевой длины.Обратите внимание: даже в режиме
MULTILINEфункцияre.match()выполняет поиск только в начале строки, а не в начале каждой строки.Если нужно найти совпадение в любом месте string, используйте вместо неё
search()(см. также search() и match()).
-
re.fullmatch(pattern, string, flags=0) -
Если вся строка string соответствует регулярному выражению pattern, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это не то же самое, что совпадение нулевой длины.Добавлено в версии 3.4.
-
re.split(pattern, string, maxsplit=0, flags=0) -
Разбивает string по вхождениям pattern. Если в pattern используются захватывающие скобки, текст всех групп шаблона также возвращается в составе результирующего списка. Если значение maxsplit ненулевое, выполняется не более maxsplit разделений, а остаток строки возвращается как последний элемент списка.
>>> re.split(r'\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split(r'\W+', 'Words, words, words.', 1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9']Если в разделителе есть захватывающие группы и он совпадает с началом строки, результат будет начинаться с пустой строки. То же самое относится к концу строки:
>>> re.split(r'(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']
Таким образом, компоненты разделителя всегда находятся по одинаковым относительным индексам в результирующем списке.
Совпадения шаблона нулевой длины разбивают строку только в том случае, если они не соседствуют с предыдущим совпадением нулевой длины.
>>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] >>> re.split(r'\W*', '...words...') ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.7: Добавлена поддержка разделения по шаблону, который может соответствовать пустой строке.
-
re.findall(pattern, string, flags=0) -
Возвращает все неперекрывающиеся совпадения pattern в string в виде списка строк или кортежей. Строка string просматривается слева направо, совпадения возвращаются в порядке обнаружения. Совпадения нулевой длины включаются в результат.
Результат зависит от количества захватывающих групп в шаблоне. Если групп нет, возвращается список строк, соответствующих всему шаблону. Если группа ровно одна, возвращается список строк, соответствующих этой группе. Если групп несколько, возвращается список кортежей строк, соответствующих группам. Незахватывающие группы не влияют на формат результата.
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10') [('width', '20'), ('height', '10')]Изменено в версии 3.7: Теперь непустые совпадения могут начинаться сразу после предыдущего совпадения нулевой длины.
-
re.finditer(pattern, string, flags=0) -
Возвращает итератор, выдающий объекты
Matchдля всех неперекрывающихся совпадений шаблона регулярного выражения pattern в string. Строка string просматривается слева направо, совпадения возвращаются в порядке обнаружения. Совпадения нулевой длины включаются в результат.Изменено в версии 3.7: Теперь непустые совпадения могут начинаться сразу после предыдущего совпадения нулевой длины.
-
re.sub(pattern, repl, string, count=0, flags=0) -
Возвращает строку, полученную заменой самых левых неперекрывающихся вхождений pattern в string на строку замены repl. Если шаблон не найден, строка string возвращается без изменений. Значение repl может быть строкой или функцией; если это строка, все escape-последовательности с обратной косой чертой обрабатываются. То есть
\nпреобразуется в один символ новой строки,\r— в возврат каретки и так далее. Неизвестные escape-последовательности с буквами ASCII зарезервированы для будущего использования и считаются ошибками. Другие неизвестные escape-последовательности, например\&, остаются без изменений. Обратные ссылки, например\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. Функция принимает единственный аргумент
Matchи возвращает строку замены. Например:>>> 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'Шаблон может быть строкой или объектом
Pattern.Необязательный аргумент count задаёт максимальное количество заменяемых вхождений шаблона; count должен быть неотрицательным целым числом. Если аргумент не указан или равен нулю, заменяются все вхождения. Совпадения шаблона нулевой длины заменяются только в том случае, если они не соседствуют с предыдущим совпадением нулевой длины, поэтому
sub('x*', '-', 'abxd')возвращает'-a-b--d-'.В строковых аргументах repl, помимо описанных выше символьных escape-последовательностей и обратных ссылок,
\g<name>использует подстроку, соответствующую группе с именемname, заданным с помощью синтаксиса(?P<name>...).\g<number>использует соответствующий номер группы; поэтому\g<2>эквивалентно\2, но не создаёт неоднозначности при замене, например,\g<2>0.\20будет интерпретировано как ссылка на группу 20, а не как ссылка на группу 2, за которой следует буквальный символ'0'. Обратная ссылка\g<0>подставляет всю подстроку, соответствующую регулярному выражению.Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.
Изменено в версии 3.6: Неизвестные escape-последовательности в pattern, состоящие из
'\'и буквы ASCII, теперь считаются ошибками.Изменено в версии 3.7: Неизвестные escape-последовательности в repl, состоящие из
'\'и буквы ASCII, теперь считаются ошибками.Изменено в версии 3.7: Совпадения шаблона нулевой длины заменяются, если они соседствуют с предыдущим непустым совпадением.
Устарело с версии 3.11: Идентификатор группы id, содержащий символы, отличные от цифр ASCII. Имя группы name, содержащее символы вне диапазона ASCII (
b'\x00'-b'\x7f'), в строках заменыbytes.
-
re.subn(pattern, repl, string, count=0, flags=0) -
Выполняет ту же операцию, что и
sub(), но возвращает кортеж(new_string, number_of_subs_made).Изменено в версии 3.1: Добавлен необязательный аргумент flags.
Изменено в версии 3.5: Несовпавшие группы заменяются пустой строкой.
-
re.escape(pattern) -
Экранирует специальные символы в pattern. Это полезно, если нужно найти произвольную буквальную строку, которая может содержать метасимволы регулярных выражений. Например:
>>> print(re.escape('https://www.python.org')) https://www\.python\.org >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:" >>> print('[%s]+' % re.escape(legal_chars)) [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+ >>> operators = ['+', '-', '*', '/', '**'] >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*Эту функцию нельзя использовать для строки замены в
sub()иsubn(); экранировать следует только обратные косые черты. Например:>>> digits_re = r'\d+' >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings' >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample)) /usr/sbin/sendmail - \d+ errors, \d+ warningsИзменено в версии 3.3: Символ
'_'больше не экранируется.Изменено в версии 3.7: Экранируются только символы, которые могут иметь специальное значение в регулярном выражении. В результате
'!','"','%',"'",',','/',':',';','<','=','>','@'и"`"больше не экранируются.
-
re.purge() -
Очищает кэш регулярных выражений.
Исключения
-
exception re.error(msg, pattern=None, pos=None) -
Исключение возникает, когда строка, переданная одной из описанных здесь функций, не является корректным регулярным выражением (например, в ней могут быть несбалансированные скобки) или когда во время компиляции либо поиска происходит другая ошибка. Отсутствие в строке совпадений с шаблоном никогда не считается ошибкой. Экземпляр исключения имеет следующие дополнительные атрибуты:
-
msg -
Неформатированное сообщение об ошибке.
-
pattern -
Шаблон регулярного выражения.
-
pos -
Индекс в pattern, на котором произошёл сбой компиляции (может быть
None).
-
lineno -
Строка, соответствующая pos (может быть
None).
-
colno -
Столбец, соответствующий pos (может быть
None).
Изменено в версии 3.5: Добавлены дополнительные атрибуты.
-
Объекты регулярных выражений
-
class re.Pattern -
Скомпилированный объект регулярного выражения, возвращаемый функцией
re.compile().Изменено в версии 3.9:
re.Patternподдерживает[]для обозначения шаблона Unicode (str) или bytes. См. Тип универсального псевдонима.
-
Pattern.search(string[, pos[, endpos]]) -
Выполняет поиск в string и находит первое место, где это регулярное выражение дает совпадение, а затем возвращает соответствующий объект
Match. Возвращает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 <re.Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # No match; search doesn't include the "d"
-
Pattern.match(string[, pos[, endpos]]) -
Если ноль или более символов в начале строки string соответствуют этому регулярному выражению, возвращает соответствующий объект
Match. Возвращает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". <re.Match object; span=(1, 2), match='o'>Если нужно найти совпадение в любом месте строки string, используйте вместо этого
search()(см. также search() и match()).
-
Pattern.fullmatch(string[, pos[, endpos]]) -
Если вся строка string соответствует этому регулярному выражению, возвращает соответствующий объект
Match. ВозвращаетNone, если строка не соответствует шаблону; обратите внимание, что это не то же самое, что совпадение нулевой длины.Необязательные параметры pos и endpos имеют тот же смысл, что и для метода
search().>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. <re.Match object; span=(1, 3), match='og'>Добавлено в версии 3.4.
-
Pattern.split(string, maxsplit=0) -
Идентичен функции
split(), но использует скомпилированный шаблон.
-
Pattern.findall(string[, pos[, endpos]]) -
Аналогичен функции
findall(), но использует скомпилированный шаблон и также принимает необязательные параметры pos и endpos, ограничивающие область поиска, как и вsearch().
-
Pattern.finditer(string[, pos[, endpos]]) -
Аналогичен функции
finditer(), но использует скомпилированный шаблон и также принимает необязательные параметры pos и endpos, ограничивающие область поиска, как и вsearch().
-
Pattern.sub(repl, string, count=0) -
Идентичен функции
sub(), но использует скомпилированный шаблон.
-
Pattern.subn(repl, string, count=0) -
Идентичен функции
subn(), но использует скомпилированный шаблон.
-
Pattern.flags -
Флаги сопоставления регулярного выражения. Это сочетание флагов, переданных в
compile(), любых(?...)встроенных флагов в шаблоне и неявных флагов, таких какUNICODE, если шаблон является строкой Unicode.
-
Pattern.groups -
Количество захватывающих групп в шаблоне.
-
Pattern.groupindex -
Словарь, сопоставляющий символьные имена групп, определенные с помощью
(?P<id>), с номерами групп. Если в шаблоне не использовались символьные группы, словарь пуст.
-
Pattern.pattern -
Строка шаблона, из которой был скомпилирован объект шаблона.
Изменено в версии 3.7: Добавлена поддержка copy.copy() и copy.deepcopy(). Скомпилированные объекты регулярных выражений считаются атомарными.
Объекты совпадения
Объекты совпадения всегда имеют логическое значение True. Поскольку match() и search() возвращают None, если совпадение не найдено, проверить наличие совпадения можно с помощью простого оператора if:
match = re.search(pattern, string)
if match:
process(match)
-
class re.Match -
Объект совпадения, возвращаемый при успешном выполнении
matchиsearch.Изменено в версии 3.9:
re.Matchподдерживает[]для обозначения совпадения Unicode (str) или bytes. См. Тип универсального псевдонима.
-
Match.expand(template) -
Возвращает строку, полученную путем подстановки обратных косых черт в строку шаблона template, как это делает метод
sub(). Экранированные последовательности, такие как\n, преобразуются в соответствующие символы, а числовые обратные ссылки (\1,\2) и именованные обратные ссылки (\g<1>,\g<name>) заменяются содержимым соответствующей группы. Обратная ссылка\g<0>заменяется всем совпадением.Изменено в версии 3.5: Несопоставленные группы заменяются пустой строкой.
-
Match.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'
-
Match.__getitem__(g) -
Это идентично
m.group(g). Это упрощает доступ к отдельной группе совпадения:>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") >>> m[0] # The entire match 'Isaac Newton' >>> m[1] # The first parenthesized subgroup. 'Isaac' >>> m[2] # The second parenthesized subgroup. 'Newton'
Поддерживаются также именованные группы:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton") >>> m['first_name'] 'Isaac' >>> m['last_name'] 'Newton'
Добавлено в версии 3.6.
-
Match.groups(default=None) -
Возвращает кортеж, содержащий все подгруппы совпадения — от 1 до последней группы в шаблоне. Аргумент default используется для групп, не участвовавших в совпадении; по умолчанию он равен
None.Например:
>>> 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')
-
Match.groupdict(default=None) -
Возвращает словарь, содержащий все именованные подгруппы совпадения, где ключами являются имена подгрупп. Аргумент default используется для групп, не участвовавших в совпадении; по умолчанию он равен
None. Например:>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.groupdict() {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
-
Match.start([group]) -
Match.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'
-
Match.span([group]) -
Для совпадения m возвращает кортеж из двух элементов
(m.start(group), m.end(group)). Обратите внимание, что если group не участвовала в совпадении, возвращается(-1, -1). По умолчанию group равен нулю — всему совпадению.
-
Match.pos -
Значение pos, переданное методу
search()илиmatch()объекта регулярного выражения. Это индекс строки, с которого механизм регулярных выражений начал поиск совпадения.
-
Match.endpos -
Значение endpos, переданное методу
search()илиmatch()объекта регулярного выражения. Это индекс строки, за который механизм регулярных выражений не выходит.
-
Match.lastindex -
Целочисленный индекс последней совпавшей захватывающей группы или
None, если ни одна группа не совпала. Например, выражения(a)b,((a)(b))и((ab))будут иметь значениеlastindex == 1при применении к строке'ab', тогда как выражение(a)(b)будет иметь значениеlastindex == 2при применении к той же строке.
-
Match.lastgroup -
Имя последней совпавшей захватывающей группы или
None, если у группы нет имени либо ни одна группа не совпала.
-
Match.re -
Объект регулярного выражения, метод
match()илиsearch()которого создал этот экземпляр совпадения.
Изменено в версии 3.7: Добавлена поддержка copy.copy() и copy.deepcopy(). Объекты совпадения считаются атомарными.
Примеры регулярных выражений
Поиск пары
В этом примере мы воспользуемся следующей вспомогательной функцией, чтобы выводить объекты совпадения в более удобном виде:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
Предположим, вы пишете программу для игры в покер, в которой рука игрока представлена строкой из 5 символов, каждый из которых обозначает карту: «a» — туз, «k» — король, «q» — дама, «j» — валет, «t» — 10, а символы от «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() объекта совпадения следующим образом:
>>> pair = re.compile(r".*(.).*\1")
>>> 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'
Имитация scanf()
В Python пока нет аналога scanf(). Регулярные выражения обычно мощнее, но и многословнее, чем строки формата scanf(). В таблице ниже приведены приблизительно эквивалентные соответствия между элементами формата scanf() и регулярными выражениями.
Элемент формата | Регулярное выражение |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Чтобы извлечь имя файла и числа из строки вида
/usr/sbin/sendmail - 0 errors, 4 warnings
нужно использовать формат scanf(), например
%s - %d errors, %d warnings
Эквивалентное регулярное выражение будет выглядеть так:
(\S+) - (\d+) errors, (\d+) warnings
search() и match()
В Python есть разные примитивные операции на основе регулярных выражений:
-
re.match()проверяет совпадение только в начале строки -
re.search()проверяет совпадение в любом месте строки (по умолчанию так работает Perl) -
re.fullmatch()проверяет, соответствует ли вся строка шаблону
Например:
>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # Match
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # No match
Регулярные выражения, начинающиеся с '^', можно использовать с search(), чтобы ограничить совпадение началом строки:
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<re.Match object; span=(0, 1), match='a'>
Однако обратите внимание, что в режиме MULTILINE функция match() сопоставляет только начало строки, тогда как search() с регулярным выражением, начинающимся с '^', будет находить совпадения в начале каждой строки.
>>> re.match("X", "A\nB\nX", re.MULTILINE) # No match
>>> re.search("^X", "A\nB\nX", re.MULTILINE) # Match
<re.Match object; span=(4, 5), match='X'>
Создание телефонной книги
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']]
Обработка текста
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.'
Поиск всех наречий
findall() находит все вхождения шаблона, а не только первое, как это делает search(). Например, если автор хочет найти все наречия в тексте, он может использовать findall() следующим образом:
>>> text = "He was carefully disguised but captured quickly by police." >>> re.findall(r"\w+ly\b", text) ['carefully', 'quickly']
Поиск всех наречий и их позиций
Если требуется получить больше сведений о совпадениях шаблона, чем просто совпавший текст, полезно использовать finditer(), поскольку она предоставляет объекты Match, а не строки. Продолжая предыдущий пример, если автор хочет найти все наречия и их позиции в тексте, он может использовать finditer() следующим образом:
>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
Синтаксис необработанных строк
Синтаксис необработанных строк (r"text") позволяет избежать сложностей с регулярными выражениями. Без него перед каждой обратной косой чертой ('\') в регулярном выражении пришлось бы ставить еще одну, чтобы экранировать ее. Например, следующие две строки кода функционально эквивалентны:
>>> re.match(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
Чтобы найти буквальную обратную косую черту, ее нужно экранировать в регулярном выражении. При использовании синтаксиса необработанных строк это означает r"\\". Без синтаксиса необработанных строк нужно использовать "\\\\", поэтому следующие строки кода функционально эквивалентны:
>>> re.match(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
Написание токенизатора
Токенизатор или сканер анализирует строку и классифицирует группы символов. Это полезный первый шаг при написании компилятора или интерпретатора.
Категории текста задаются регулярными выражениями. Идея состоит в том, чтобы объединить их в одно общее регулярное выражение и перебрать последовательные совпадения:
from typing import NamedTuple
import re
class Token(NamedTuple):
type: str
value: str
line: int
column: int
def tokenize(code):
keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
token_specification = [
('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
('ASSIGN', r':='), # Assignment operator
('END', r';'), # Statement terminator
('ID', r'[A-Za-z]+'), # Identifiers
('OP', r'[+\-*/]'), # Arithmetic operators
('NEWLINE', r'\n'), # Line endings
('SKIP', r'[ \t]+'), # Skip over spaces and tabs
('MISMATCH', r'.'), # Any other character
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group()
column = mo.start() - line_start
if kind == 'NUMBER':
value = float(value) if '.' in value else int(value)
elif kind == 'ID' and value in keywords:
kind = value
elif kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
continue
elif kind == 'SKIP':
continue
elif kind == 'MISMATCH':
raise RuntimeError(f'{value!r} unexpected on line {line_num}')
yield Token(kind, value, line_num, column)
statements = '''
IF quantity THEN
total := total + price * quantity;
tax := price * 0.05;
ENDIF;
'''
for token in tokenize(statements):
print(token)
Токенизатор выдает следующий результат:
Token(type='IF', value='IF', line=2, column=4) Token(type='ID', value='quantity', line=2, column=7) Token(type='THEN', value='THEN', line=2, column=16) Token(type='ID', value='total', line=3, column=8) Token(type='ASSIGN', value=':=', line=3, column=14) Token(type='ID', value='total', line=3, column=17) Token(type='OP', value='+', line=3, column=23) Token(type='ID', value='price', line=3, column=25) Token(type='OP', value='*', line=3, column=31) Token(type='ID', value='quantity', line=3, column=33) Token(type='END', value=';', line=3, column=41) Token(type='ID', value='tax', line=4, column=8) Token(type='ASSIGN', value=':=', line=4, column=12) Token(type='ID', value='price', line=4, column=15) Token(type='OP', value='*', line=4, column=21) Token(type='NUMBER', value=0.05, line=4, column=23) Token(type='END', value=';', line=4, column=27) Token(type='ENDIF', value='ENDIF', line=5, column=4) Token(type='END', value=';', line=5, column=9)
Фридл, Джеффри. «Мастерство регулярных выражений». 3-е изд., O’Reilly Media, 2009. В третьем издании книги Python уже совсем не рассматривается, однако в первом издании подробно описывается написание качественных шаблонов регулярных выражений.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/re.html