Сообщить об ошибке.

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

Новое в Python 3.11: Механизм сопоставления регулярных выражений модуля re был частично переработан и теперь использует вычисляемые переходы (или "поточный код") на поддерживаемых платформах. В результате Python 3.11 выполняет тесты регулярных выражений pyperformance на 10% быстрее, чем Python 3.10.

Синтаксис регулярных выражений в Python немного отличается от синтаксиса регулярных выражений в языке программирования PERL.

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

Для получения дополнительной информации смотрите раздел сайта docs-python.ru "Использование регулярных выражений в Python"

Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, таких как 'A', 'a' или '0', являются простейшими регулярными выражениями, они просто соответствуют друг другу. Вы можете объединять обычные символы, поэтому выражение last соответствует строке 'last'.

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

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

Содержание:


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

- '.' - точка:

В режиме по умолчанию '.' соответствует любому символу, кроме новой строки. Если указан флаг re.DOTALL, он соответствует любому символу, включая символ новой строки \n.

- '^'

Специальный символ '^' соответствует началу строки, а при включенном флаге re.MULTILINE также соответствует положению сразу после каждой новой строки.

- '$'

Специальный символ '$' соответствует концу строки или непосредственно перед новой строкой в ​​конце строки, а при включенном флаге re.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' и не будет соответствовать просто символу 'а'.

- '?'

Специальный символ '?' заставляет результирующее регулярное выражение совпадать с 0 или 1 повторениями предыдущего регулярного выражения. Выражение ab? будет соответствовать либо 'а' или 'ab'.

- '*?', '+?', '??'

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

- '*+', '++', '?+'

Притяжательные квантификаторы '*+', '++', '?+' (новое в Python 3.11) работают подобно кванторам '*', '+' и '?' (также совпадают как можно больше раз), НО в отличие от истинных жадных кванторов, они не допускают обратного отслеживания, когда следующее за ними выражение не совпадает.

Например, a*a будет соответствовать 'aaaa', потому что a* будет соответствовать всем 4 'a', но, когда встречается последнее 'a', выражение возвращается назад, так что в итоге a* в конечном итоге соответствует 3 'a', а четвертое 'a' соответствует окончательному 'а'. Однако, когда a*+a используется для сопоставления с 'aaaa', a*+ будет соответствовать всем 4 'a', но когда конечному 'a' не удается найти больше подходящих символов, то выражение не может быть восстановлено и, таким образом, не будет соответствовать.

Другими словами, регулярные выражения x*+, x++ и x?+ эквивалентны (?>x*), (?>x+) и (?>x?) соответственно.

Новое в Python 3.11

- '{m}'

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

- '{m,n}'

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

- '{m,n}?'

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

- '{m,n}+'

Конструкция '{m,n}+' (добавлена в Python 3.11) заставляет результирующее регулярное выражение соответствовать от m до n повторений предыдущего регулярного выражения, пытаясь сопоставить как можно больше повторений, не устанавливая никаких точек возврата. Это притяжательная версия приведенной выше конструкции.

Например, в 6-символьной строке 'aaaaaa' регулярное выражение 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}).

Новое в Python 3.11

- '\'

Специальный символ '\' либо экранирует специальные символы, разрешающие соответствовать символам, таким как '*', '?' и так далее или сигнализирует о специальной последовательности, которые будут обсуждаются ниже.

Если не использовать необработанную строку r'' в написании шаблона регулярного выражения, то необходимо помнить, что Python также использует обратную косую черту в качестве [escape-последовательности][escape-sequence] в строковых литералах. Если escape-последовательность не распознается синтаксическим анализатором Python, обратная косая черта и последующий символ включаются в полученную строку. Если Python распознает полученную последовательность, обратный слеш должен повторяться дважды. Это сложно и трудно понять, поэтому настоятельно рекомендуется использовать необработанные строки r'' для всех, кроме самых простых регулярных выражений.

- '[]'

Конструкция '[]' используется для обозначения символьного класса:

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

- '|'

Выражение A|B, где A и B могут быть произвольными регулярными выражениями, создает выражение, которое будет соответствовать либо A, либо B. Таким образом '|' может быть разделено произвольное число регулярных выражений. Это можно использовать и внутри групп. При сканировании строки, регулярные выражения разделенные символом '|' проверяют совпадения слева направо. Когда один из шаблонов полностью совпадает, эта ветвь принимается. Это означает, что если A совпало, то B не будет проверяться дальше, даже если это приведет к более длительному общему соответствию. Другими словами, оператор ' | ' никогда не бывает жадным.

Чтобы сопоставить литерал '|', используйте \| или заключите его в символьный класс, как [|].

- '(...)'

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

Расширения регулярных выражений:

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

- '(?aiLmsux)'

Конструкция '(?aiLmsux)' обозначает один или несколько букв из набора 'a', 'i', 'L', 'm', 's', 'u', 'x'. Группа соответствует пустой строке. Буквы устанавливают соответствующие флаги:

  • re.A - сопоставление только в ASCII,
  • re.I - игнорирование регистра,
  • re.L - в зависимости от локали,
  • re.M - многострочный,
  • re.S - точка соответствует всем,
  • re.U - сопоставление в Юникоде
  • re.X - режим отладки.

Флаги описаны в разделе "Флаги регулярных выражений в Python". Конструкция полезна, если необходимо включить флаги как часть регулярного выражения вместо передачи аргумента флага в функцию re.compile(). Флаги должны использоваться первыми в строке шаблона регулярного выражения.

Изменено в Python 3.11: Эту конструкцию можно использовать только в начале выражения.

- '(?aiLmsux-imsx:...)'

Конструкция '(?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 - сопоставление в Юникоде
  • re.X - режим отладки.

Флаги описаны в разделе "Флаги регулярных выражений в Python".

При использовании в качестве встроенных флагов 'a', 'L' и 'u' являются взаимоисключающими, поэтому они не могут быть объединены или следовать за '-'. Вместо этого, когда один из них появляется во встроенной группе, он переопределяет соответствующий режим во включающей группе. В шаблонах Unicode (?a:...) переключается на сопоставление только ASCII, и (?u:...) на сопоставление Unicode (по умолчанию). В байтовом шаблоне (?L:...) переключается на соответствие в зависимости от локали и (?a:...) переключается на соответствие только ASCII ( по умолчанию). Это переопределение действует только для узкой встроенной группы и исходный режим сопоставления восстанавливается вне группы.

- '(?>...)'

Конструкция '(?>...)' (добавлена в Python 3.11) попытается сопоставить регулярное выражение '...' как если бы это было отдельное выражение, и в случае успеха продолжает сопоставляться с остальным шаблоном, следующим за ним. Если последующий шаблон не соответствует, то стек может быть раскручен только до точки перед (?>...), потому что после выхода, выражение, известное как атомарная группа, отбрасывает все точки стека внутри себя. Таким образом, (?>.*). никогда не будет соответствовать чему-либо, потому что сначала .* будет соответствовать всем возможным символам, а затем, когда ничего не останется, окончательный . просто не сможет соответствовать чему либо. Поскольку в атомной группе не сохраняются точки стека и перед ней нет точки стека, все выражение, таким образом, не будет совпадать.

Новое в Python 3.11.

- '(?:...)'

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

- '(?P<name>...)'

Конструкция '(?P<name>...)' называется именованной группой, работает аналогично обычной группе (...). Совпавшая подстрока захватывается этой группой и доступна для последующего извлечения через символическое имя группы name. В шаблоне регулярного выражения имена групп должны быть действительными идентификаторами Python и каждое имя группы должно быть определено только один раз. Именованная группа также является пронумерованной группой, как если бы она была простой группой.

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

  • по той же самой схеме: (?P=quote) или \1;
  • при обработке объекта сопоставления m: m.group('quote') или m.end('quote') и так далее;
  • в строке, переданной в аргумент repl функции re.sub(): '\g<quote>' или '\g<1>' или '\1'.

Устарело, начиная с Python 3.11: имена групп, содержащие символы, отличные от ASCII, в шаблонах байтов.

- '(?P=name)'

Конструкция '(?P=name)' обозначает обратную ссылку на именованную группу. Это соответствует любому совпавшему тексту, который был сопоставлен с более ранней группой с именем name.

- '(?#...)'

Конструкция '(?#...)' обозначает комментарий. Содержимое скобок просто игнорируется.

- '(?=...)'

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

- '(?!...)'

Конструкция '(?!...)' называется опережающей негативной проверкой, где ... регулярное выражение, которое определяет проверяемую позицию справа от основного выражения. Например выражение Isaac (?!Asimov) будет соответствовать 'Isaac ', только если за ним не следует 'Asimov'.

- '(?<=...)'

Конструкция '(?<=...)' называется позитивной ретроспективной проверкой, где ... регулярное выражение, которое определяет проверяемую позицию слева от основного выражения.

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

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

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

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

- '(?<!...)'

Конструкция '(?<!...)' называется негативной ретроспективной проверкой, где ... регулярное выражение, которое определяет проверяемую позицию слева от основного выражения. Подобно положительным проверкам, шаблон регулярного выражения должен соответствовать только строкам фиксированной длины. Шаблоны регулярных выражений, которые начинаются с негативной ретроспективной проверки могут совпадать в начале искомой строки.

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

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

Устарело, начиная с Python 3.11: идентификатор группы, содержащий все, кроме цифр ASCII.

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

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

- '\number'

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

- '\A'

Специальная последовательность '\A' совпадает только с положением начала строки.

- '\b'

Специальная последовательность '\b' соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность буквенно-цифровых символов. Обратите внимание, что формально '\b' определяется как граница между '\w' и '\W' специальными последовательностями или наоборот, или между '\w' началом и концом строки. Это означает, что выражение r'\bfoo\b' покажет совпадение в строках 'foo', ' foo.', '(foo)', 'bar foo baz' но не 'foobar' или 'foo3'.

По умолчанию буквенно-цифровые символы Unicode используются в шаблонах Unicode, но это можно изменить с помощью флага re.ASCII. Границы слова определяются текущей локалью, если используется флаг LOCALE. Внутри символьного класса '\b' представляет символ backspace для совместимости со строковыми литералами Python.

- '\B'

Специальная последовательность '\B' соответствует пустой строке, но только если она не находится в начале или конце слова. Это означает, что выражение r'py\B' покажет совпадение в строках 'python', 'py3', 'py2', но не 'py', 'py.', или 'py!'. Последовательность \B - это как раз противоположность \b, поэтому символы слов в шаблонах Unicode являются буквенно-цифровыми символами Unicode или подчеркиванием, хотя это может быть изменено с помощью флага ASCII. Границы слов определяются текущей локализацией, если используется флаг локали LOCALE.

- '\d'

Для шаблонов строк Unicode: специальная последовательность '\d' соответствует любой десятичной цифре Unicode, то есть любому символу в категории символов Unicode [Nd]. Это включает в себя диапазон [0-9], а также много других цифровых символов. Если используется флаг re.ASCII, то эквивалентно символьному классу [0-9].

Для шаблонов байтовых строк: специальная последовательность '\d' соответствует любой десятичной цифре, эквивалентно символьному классу [0-9].

- '\D'

Специальная последовательность '\D' соответствует любому символу, который не является десятичной цифрой. Это противоположность \d. Если используется флаг re.ASCII, то '\D' становится эквивалентно символьному классу [^0-9].

- '\s'

Для шаблонов строк Unicode: специальная последовательность '\s' соответствует пробельным символам Unicode, включая и многие другие символы, например неразрывные пробелы, предписанные правилами типографики во многих языках. Если используется флаг re.ASCII, то '\s' совпадает только с символьным классом [ \t\n\r\f\v].

Для шаблонов байтовых строк: специальная последовательность '\s' соответствует символам, которые считаются пробелами в наборе символов ASCII, что эквивалентно символьному классу [ \t\n\r\f\v].

- '\S'

Специальная последовательность '\S' соответствует любому символу, который не является пробельным символом. Это противоположность \s. Если используется флаг re.ASCII, то '\S' эквивалентно символьному классу [^ \t\n\r\f\v].

- '\w'

Для шаблонов строк Unicode: специальная последовательность '\w' соответствует символам Unicode, что включает в себя большинство символов, которые могут быть частью слова на любом языке, а также цифры и подчеркивание. Если используется флаг re.ASCII, то '\w' становится эквивалентно символьному классу [a-zA-Z0-9_].

Для шаблонов байтовых строк: специальная последовательность '\w' соответствует символам, которые считаются буквенно-цифровыми символами ASCII, что эквивалентно символьному классу [a-zA-Z0-9_]. Если используется флаг re.LOCALE, то '\w' соответствует символам, которые являются буквенно-цифровыми в текущей локали + символ подчеркивания.

- '\W'

Специальная последовательность '\W' соответствует любому символу, который не является символом слова. Это противоположность \w. Если используется флаг re.ASCII, то '\W' становится эквивалентно символьному классу [^a-zA-Z0-9_]. Если используется флаг re.LOCALE, то '\W' соответствует символам, которые НЕ являются буквенно-цифровыми символами в текущей локали + символ подчеркивания.

- '\Z'

Специальная последовательность '\Z' совпадает только с положением конца строки.

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

\a      \b      \f      \n
\N      \r      \t      \u
\U      \v      \x      \\

Обратите внимание, что \b используется для представления границ слов и означает "возврат" только внутри классов символов.

[Escape-последовательности][escape-sequence] '\u', '\U' и '\N' распознаются только в шаблонах строк Unicode. В шаблонах байтовых строк они являются ошибками. Неизвестные экранированные символы ASCII зарезервированы для будущего использования и рассматриваются как ошибки.