re — Операції регулярних виразів

Source code: Lib/re/


Цей модуль забезпечує операції зіставлення регулярних виразів, подібні до тих, які є в Perl.

Both patterns and strings to be searched can be Unicode strings (str) as well as 8-bit strings (bytes). However, Unicode strings and 8-bit strings cannot be mixed: that is, you cannot match a Unicode string with a bytes pattern or vice-versa; similarly, when asking for a substitution, the replacement string must be of the same type as both the pattern and the search string.

Regular expressions use the backslash character ('\') to indicate special forms or to allow special characters to be used without invoking their special meaning. This collides with Python’s usage of the same character for the same purpose in string literals; for example, to match a literal backslash, one might have to write '\\\\' as the pattern string, because the regular expression must be \\, and each backslash must be expressed as \\ inside a regular Python string literal. Also, please note that any invalid escape sequences in Python’s usage of the backslash in string literals now generate a SyntaxWarning and in the future this will become a SyntaxError. This behaviour will happen even if it is a valid escape sequence for a regular expression.

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

Важливо відзначити, що більшість операцій з регулярними виразами доступні як функції та методи на рівні модуля для компільованих регулярних виразів. Функції — це ярлики, які не потребують компіляції об’єкта регулярного виразу, але пропускають деякі параметри тонкого налаштування.

Дивись також

The third-party regex module, which has an API compatible with the standard library re module, but offers additional functionality and a more thorough Unicode support.

Синтаксис регулярного виразу

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

Регулярні вирази можна об’єднувати для створення нових регулярних виразів; якщо A і B є регулярними виразами, то AB також є регулярним виразом. Загалом, якщо рядок p відповідає A, а інший рядок q відповідає B, рядок pq відповідатиме AB. Це справедливо, якщо A або B не містять операції з низьким пріоритетом; граничні умови між A і B; або мають пронумеровані посилання на групи. Таким чином, складні вирази можна легко побудувати з простіших примітивних виразів, таких як описані тут. Щоб отримати детальну інформацію про теорію та реалізацію регулярних виразів, зверніться до книги Фрідла [Frie09] або майже до будь-якого підручника про побудову компілятора.

Нижче наведено коротке пояснення формату регулярних виразів. Для отримання додаткової інформації та більш щадної презентації зверніться до Регулярний вираз HOWTO.

Регулярні вирази можуть містити як спеціальні, так і звичайні символи. Більшість звичайних символів, таких як 'A', 'a' або '0', є найпростішими регулярними виразами; вони просто збігаються. Ви можете об’єднувати звичайні символи, тому last збігається з рядком 'last'. (У решті цього розділу ми будемо писати RE в цим особливим стилі, як правило, без лапок, а рядки для відповідності одинарних лапках.)

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

Repetition operators or quantifiers (*, +, ?, {m,n}, etc) cannot be directly nested. This avoids ambiguity with the non-greedy modifier suffix ?, and with other modifiers in other implementations. To apply a second repetition to an inner repetition, parentheses may be used. For example, the expression (?:a{6})* matches any multiple of six 'a' characters.

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

.

(Точка.) У режимі за замовчуванням це відповідає будь-якому символу, крім символу нового рядка. Якщо вказано прапорець DOTALL, він відповідає будь-якому символу, включаючи новий рядок.

^

(Caret.) Збігається з початком рядка, а в режимі MULTILINE також збігається одразу після кожного нового рядка.

$

Збігається з кінцем рядка або безпосередньо перед символом нового рядка в кінці рядка, а в режимі MULTILINE також збігається перед символом нового рядка. foo відповідає як „foo“, так і „foobar“, тоді як регулярний вираз foo$ відповідає лише „foo“. Що ще цікавіше, пошук foo.$ у 'foo1\nfoo2\n'' зазвичай відповідає „foo2“, але „foo1“ у режимі MULTILINE; пошук одного $ у 'foo\n' знайде два (порожні) збіги: один безпосередньо перед символом нового рядка та один у кінці рядка.

*

Примушує кінцевий RE відповідати 0 або більше повторень попереднього RE, якомога більше повторень. ab* відповідатиме „a“, „ab“ або „a“, за якими йде будь-яка кількість „b“.

+

Примушує кінцевий RE відповідати 1 або більше повторень попереднього RE. ab+ відповідатиме „a“, за яким слідує будь-яке ненульове число „b“; воно не збігатиметься лише з «а».

?

Примушує результуюче RE відповідати 0 або 1 повторенням попереднього RE. ab? відповідатиме або „a“, або „ab“.

*?, +?, ??

The '*', '+', and '?' quantifiers are all greedy; they match as much text as possible. Sometimes this behaviour isn’t desired; if the RE <.*> is matched against '<a> b <c>', it will match the entire string, and not just '<a>'. Adding ? after the quantifier makes it perform the match in non-greedy or minimal fashion; as few characters as possible will be matched. Using the RE <.*?> will match only '<a>'.

*+, ++, ?+

Like the '*', '+', and '?' quantifiers, those where '+' is appended also match as many times as possible. However, unlike the true greedy quantifiers, these do not allow back-tracking when the expression following it fails to match. These are known as possessive quantifiers. For example, a*a will match 'aaaa' because the a* will match all 4 'a's, but, when the final 'a' is encountered, the expression is backtracked so that in the end the a* ends up matching 3 'a's total, and the fourth 'a' is matched by the final 'a'. However, when a*+a is used to match 'aaaa', the a*+ will match all 4 'a', but when the final 'a' fails to find any more characters to match, the expression cannot be backtracked and will thus fail to match. x*+, x++ and x?+ are equivalent to (?>x*), (?>x+) and (?>x?) correspondingly.

Added in version 3.11.

{m}

Вказує, що точно m копій попереднього RE мають відповідати; менша кількість збігів призводить до того, що весь RE не збігається. Наприклад, a{6} відповідатиме рівно шести символам 'a', але не п’яти.

{m,n}

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

{m,n}?

Causes the resulting RE to match from m to n repetitions of the preceding RE, attempting to match as few repetitions as possible. This is the non-greedy version of the previous quantifier. For example, on the 6-character string 'aaaaaa', a{3,5} will match 5 'a' characters, while a{3,5}? will only match 3 characters.

{m,n}+

Causes the resulting RE to match from m to n repetitions of the preceding RE, attempting to match as many repetitions as possible without establishing any backtracking points. This is the possessive version of the quantifier above. For example, on the 6-character string 'aaaaaa', a{3,5}+aa attempt to match 5 'a' characters, then, requiring 2 more 'a's, will need more characters than available and thus fail, while a{3,5}aa will match with a{3,5} capturing 5, then 4 'a's by backtracking and then the final 2 'a's are matched by the final aa in the pattern. x{m,n}+ is equivalent to (?>x{m,n}).

Added in version 3.11.

\

Або екранує спеціальні символи (дозволяючи вам зіставляти такі символи, як '*', '?'' і так далі), або сигналізує про спеціальну послідовність; спеціальні послідовності обговорюються нижче.

Якщо ви не використовуєте необроблений рядок для вираження шаблону, пам’ятайте, що Python також використовує зворотну косу риску як керуючу послідовність у рядкових літералах; якщо escape-послідовність не розпізнається синтаксичним аналізатором Python, зворотна коса риска та наступний символ включаються в результуючий рядок. Однак, якщо Python розпізнає отриману послідовність, зворотну косу риску слід повторити двічі. Це складно і важко зрозуміти, тому настійно рекомендується використовувати необроблені рядки для всіх виразів, крім найпростіших.

[]

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

  • Символи можуть бути перераховані окремо, напр. «[amk]» відповідатиме «a», «m» або «k».

  • Діапазони символів можна вказати, вказавши два символи та розділивши їх символом '-', наприклад, [a-z] відповідатиме будь-якій літері ASCII у нижньому регістрі, [0-5][0-9]. ] відповідатиме всім двозначним числам від 00 до 59, а [0-9A-Fa-f] відповідатиме будь-якій шістнадцятковій цифрі. Якщо - є екранованим (наприклад, [a\-z]) або якщо він розміщений як перший чи останній символ (наприклад [-a] або [a-] ), він відповідатиме літералу '-'.

  • Спеціальні символи втрачають своє особливе значення в наборах. Наприклад, [(+*)] відповідатиме будь-якому з літеральних символів '(', '+', '*' або ')'.

  • Character classes such as \w or \S (defined below) are also accepted inside a set, although the characters they match depend on the flags used.

  • Символи, які не входять до діапазону, можуть бути зіставлені шляхом complementing набору. Якщо першим символом набору є '^', усі символи, яких не в наборі, будуть зіставлені. Наприклад, [^5] відповідатиме будь-якому символу, крім '5'', а [^^] відповідатиме будь-якому символу, крім '^'. ^ не має особливого значення, якщо це не перший символ у наборі.

  • To match a literal ']' inside a set, precede it with a backslash, or place it at the beginning of the set. For example, both [()[\]{}] and []()[{}] will match a right bracket, as well as left bracket, braces, and parentheses.

  • У майбутньому може бути додано підтримку вкладених наборів і операцій із наборами, як у технічному стандарті Unicode #18. Це призведе до зміни синтаксису, тож для полегшення цієї зміни FutureWarning наразі буде викликано у неоднозначних випадках. Це включає в себе набори, що починаються з літерала '[' або містять літеральні послідовності символів '--', '&&', '~~' і '| |'. Щоб уникнути попередження, екрануйте їх зворотною скісною рискою.

Змінено в версії 3.7: FutureWarning викликається, якщо набір символів містить конструкції, які семантично зміняться в майбутньому.

|

A|B, де A і B можуть бути довільними RE, створює регулярний вираз, який відповідатиме A або B. Таким чином довільна кількість RE може бути розділена символом '|'. Це також можна використовувати всередині груп (див. нижче). Під час сканування цільового рядка RE, розділені '|', пробуються зліва направо. Якщо один шаблон повністю збігається, ця гілка приймається. Це означає, що як тільки A збігається, B більше не перевірятиметься, навіть якщо це призведе до довшого загального збігу. Іншими словами, оператор '|'' ніколи не є жадібним. Щоб відповідати літералу '|', використовуйте \| або вкладіть його в клас символів, як у [|].

(...)

Збігається з будь-яким регулярним виразом у дужках і вказує на початок і кінець групи; вміст групи може бути отриманий після того, як було виконано збіг, і може бути зіставлений пізніше в рядку за допомогою спеціальної послідовності \number, описаної нижче. Щоб зіставити літерали '(' або ')', використовуйте \( або \) або вкладіть їх у клас символів: [(] , [)].

(?...)

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

(?aiLmsux)

(One or more letters from the set 'a', 'i', 'L', 'm', 's', 'u', 'x'.) The group matches the empty string; the letters set the corresponding flags for the entire regular expression:

  • re.A (ASCII-only matching)

  • re.I (ignore case)

  • re.L (locale dependent)

  • re.M (multi-line)

  • re.S (dot matches all)

  • re.U (Unicode matching)

  • re.X (verbose)

(The flags are described in Зміст модуля.) This is useful if you wish to include the flags as part of the regular expression, instead of passing a flag argument to the re.compile() function. Flags should be used first in the expression string.

Змінено в версії 3.11: This construction can only be used at the start of the expression.

(?:...)

Версія звичайних круглих дужок без захоплення. Збігається з будь-яким регулярним виразом у дужках, але підрядок, який відповідає групі, неможливо отримати після виконання збігу або посилатися на нього пізніше в шаблоні.

(?aiLmsux-imsx:...)

(Zero or more letters from the set 'a', 'i', 'L', 'm', 's', 'u', 'x', optionally followed by '-' followed by one or more letters from the 'i', 'm', 's', 'x'.) The letters set or remove the corresponding flags for the part of the expression:

  • re.A (ASCII-only matching)

  • re.I (ignore case)

  • re.L (locale dependent)

  • re.M (multi-line)

  • re.S (dot matches all)

  • re.U (Unicode matching)

  • re.X (verbose)

(The flags are described in Зміст модуля.)

The letters 'a', 'L' and 'u' are mutually exclusive when used as inline flags, so they can’t be combined or follow '-'. Instead, when one of them appears in an inline group, it overrides the matching mode in the enclosing group. In Unicode patterns (?a:...) switches to ASCII-only matching, and (?u:...) switches to Unicode matching (default). In bytes patterns (?L:...) switches to locale dependent matching, and (?a:...) switches to ASCII-only matching (default). This override is only in effect for the narrow inline group, and the original matching mode is restored outside of the group.

Added in version 3.6.

Змінено в версії 3.7: Літери 'a', 'L' і 'u' також можна використовувати в групі.

(?>...)

Attempts to match ... as if it was a separate regular expression, and if successful, continues to match the rest of the pattern following it. If the subsequent pattern fails to match, the stack can only be unwound to a point before the (?>...) because once exited, the expression, known as an atomic group, has thrown away all stack points within itself. Thus, (?>.*). would never match anything because first the .* would match all characters possible, then, having nothing left to match, the final . would fail to match. Since there are no stack points saved in the Atomic Group, and there is no stack point before it, the entire expression would thus fail to match.

Added in version 3.11.

(?P <name> ...)

Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. Group names must be valid Python identifiers, and in bytes patterns they can only contain bytes in the ASCII range. Each group name must be defined only once within a regular expression. A symbolic group is also a numbered group, just as if the group were not named.

На іменовані групи можна посилатися в трьох контекстах. Якщо шаблон (?P <quote> ['"]).*?(?P=quote) (тобто відповідає рядку в одинарних або подвійних лапках):

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

Способи посилання на нього

за таким самим шаблоном

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

  • \1

під час обробки відповідного об’єкта m

  • m.group('quote')

  • m.end('quote') (і т.д.)

у рядку, переданому в аргумент repl re.sub()

  • \g <quote>

  • \g <1>

  • \1

Змінено в версії 3.12: In bytes patterns, group name can only contain bytes in the ASCII range (b'\x00'-b'\x7f').

(?P=name)

Зворотне посилання на іменовану групу; він відповідає будь-якому тексту, який відповідав попередній групі під назвою name.

(?#...)

коментар; вміст круглих дужок просто ігнорується.

(?=...)

Збігається, якщо ... збігається наступним, але не споживає жоден рядок. Це називається lookahead assertion. Наприклад, Isaac (?=Azimov) відповідатиме 'Isaac '', лише якщо за ним йде 'Azimov'.

(?!...)

Збігається, якщо ... не збігається наступним. Це негативне випереджальне твердження. Наприклад, Isaac (?!Azimov) відповідатиме 'Isaac '', лише якщо за ним не йде 'Azimov'.

(?<=...)

Збігається, якщо поточній позиції в рядку передує відповідність для ..., яка закінчується на поточній позиції. Це називається позитивним ретроспективним твердженням. (?<=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: Додано підтримку групових посилань фіксованої довжини.

(?<!...)

Збігається, якщо поточній позиції в рядку не передує збіг для .... Це називається negative lookbehind assertion. Подібно до позитивних ретроспективних тверджень, шаблон, що міститься, повинен відповідати лише рядкам певної фіксованої довжини. Шаблони, які починаються з негативних ретроспективних тверджень, можуть збігатися на початку рядка, який шукається.

(?(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' nor 'user@host.com> '.

Змінено в версії 3.12: Group id can only contain ASCII digits. In bytes patterns, group name can only contain bytes in the ASCII range (b'\x00'-b'\x7f').

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

\номер

Відповідає вмісту групи з тим самим номером. Групи нумеруються, починаючи з 1. Наприклад, (.+) \1 відповідає 'the' або '55 55', але не 'thethe' (примітка пробіл після групи). Цю спеціальну послідовність можна використовувати лише для відповідності одній із перших 99 груп. Якщо перша цифра числа дорівнює 0 або число складається з 3 вісімкових цифр, це не буде інтерпретовано як збіг групи, а як символ із вісімковим значенням число. Усередині '[' і ']' класу символів усі цифрові екрановані символи розглядаються як символи.

\A

Збігається лише на початку рядка.

\b

Matches the empty string, but only at the beginning or end of a word. A word is defined as a sequence of word characters. Note that formally, \b is defined as the boundary between a \w and a \W character (or vice versa), or between \w and the beginning or end of the string. This means that r'\bat\b' matches 'at', 'at.', '(at)', and 'as at ay' but not 'attempt' or 'atlas'.

The default word characters in Unicode (str) patterns are Unicode alphanumerics and the underscore, but this can be changed by using the ASCII flag. Word boundaries are determined by the current locale if the LOCALE flag is used.

Примітка

Inside a character range, \b represents the backspace character, for compatibility with Python’s string literals.

\B

Matches the empty string, but only when it is not at the beginning or end of a word. This means that r'at\B' matches 'athens', 'atom', 'attorney', but not 'at', 'at.', or 'at!'. \B is the opposite of \b, so word characters in Unicode (str) patterns are Unicode alphanumerics or the underscore, although this can be changed by using the ASCII flag. Word boundaries are determined by the current locale if the LOCALE flag is used.

\d
Для шаблонів Unicode (str):

Matches any Unicode decimal digit (that is, any character in Unicode character category [Nd]). This includes [0-9], and also many other digit characters.

Matches [0-9] if the ASCII flag is used.

Для 8-бітових (байтових) шаблонів:

Matches any decimal digit in the ASCII character set; this is equivalent to [0-9].

\D

Matches any character which is not a decimal digit. This is the opposite of \d.

Matches [^0-9] if the ASCII flag is used.

\s
Для шаблонів Unicode (str):

Matches Unicode whitespace characters (which includes [ \t\n\r\f\v], and also many other characters, for example the non-breaking spaces mandated by typography rules in many languages).

Matches [ \t\n\r\f\v] if the ASCII flag is used.

Для 8-бітових (байтових) шаблонів:

Відповідає символам, які вважаються пробілами в наборі символів ASCII; це еквівалентно [ \t\n\r\f\v].

\S

Matches any character which is not a whitespace character. This is the opposite of \s.

Matches [^ \t\n\r\f\v] if the ASCII flag is used.

\w
Для шаблонів Unicode (str):

Matches Unicode word characters; this includes all Unicode alphanumeric characters (as defined by str.isalnum()), as well as the underscore (_).

Matches [a-zA-Z0-9_] if the ASCII flag is used.

Для 8-бітових (байтових) шаблонів:

Matches characters considered alphanumeric in the ASCII character set; this is equivalent to [a-zA-Z0-9_]. If the LOCALE flag is used, matches characters considered alphanumeric in the current locale and the underscore.

\W

Matches any character which is not a word character. This is the opposite of \w. By default, matches non-underscore (_) characters for which str.isalnum() returns False.

Matches [^a-zA-Z0-9_] if the ASCII flag is used.

If the LOCALE flag is used, matches characters which are neither alphanumeric in the current locale nor the underscore.

\Z

Збігається лише в кінці рядка.

Most of the escape sequences supported by Python string literals are also accepted by the regular expression parser:

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

(Зауважте, що \b використовується для представлення меж слів і означає «backspace» лише всередині класів символів.)

'\u', '\U', and '\N' escape sequences are only recognized in Unicode (str) patterns. In bytes patterns they are errors. Unknown escapes of ASCII letters are reserved for future use and treated as errors.

Вісімкові втечі включені в обмеженій формі. Якщо першою цифрою є 0 або є три вісімкові цифри, це вважається вісімковим екрануванням. В іншому випадку це посилання на групу. Що стосується рядкових літералів, вісімкові символи екранування завжди мають не більше трьох цифр.

Змінено в версії 3.3: Було додано керуючі послідовності '\u' і '\U'.

Змінено в версії 3.6: Невідомі вихідні символи, що складаються з '\' і літери ASCII, тепер є помилками.

Змінено в версії 3.8: The '\N{name}' escape sequence has been added. As in string literals, it expands to the named Unicode character (e.g. '\N{EM DASH}').

Зміст модуля

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

Прапори

Змінено в версії 3.6: Константи прапорів тепер є екземплярами RegexFlag, який є підкласом enum.IntFlag.

class re.RegexFlag

An enum.IntFlag class containing the regex options listed below.

Added in version 3.11: - added to __all__

re.A
re.ASCII

Make \w, \W, \b, \B, \d, \D, \s and \S perform ASCII-only matching instead of full Unicode matching. This is only meaningful for Unicode (str) patterns, and is ignored for bytes patterns.

Corresponds to the inline flag (?a).

Примітка

The U flag still exists for backward compatibility, but is redundant in Python 3 since matches are Unicode by default for str patterns, and Unicode matching isn’t allowed for bytes patterns. UNICODE and the inline flag (?u) are similarly redundant.

re.DEBUG

Display debug information about compiled expression.

No corresponding inline flag.

re.I
re.IGNORECASE

Perform case-insensitive matching; expressions like [A-Z] will also match lowercase letters. Full Unicode matching (such as Ü matching ü) also works unless the ASCII flag is used to disable non-ASCII matches. The current locale does not change the effect of this flag unless the LOCALE flag is also used.

Corresponds to the inline flag (?i).

Note that when the Unicode patterns [a-z] or [A-Z] are used in combination with the IGNORECASE flag, they will match the 52 ASCII letters and 4 additional non-ASCII letters: „İ“ (U+0130, Latin capital letter I with dot above), „ı“ (U+0131, Latin small letter dotless i), „ſ“ (U+017F, Latin small letter long s) and „K“ (U+212A, Kelvin sign). If the ASCII flag is used, only letters „a“ to „z“ and „A“ to „Z“ are matched.

re.L
re.LOCALE

Make \w, \W, \b, \B and case-insensitive matching dependent on the current locale. This flag can be used only with bytes patterns.

Corresponds to the inline flag (?L).

Попередження

This flag is discouraged; consider Unicode matching instead. The locale mechanism is very unreliable as it only handles one «culture» at a time and only works with 8-bit locales. Unicode matching is enabled by default for Unicode (str) patterns and it is able to handle different locales and languages.

Змінено в версії 3.6: LOCALE can be used only with bytes patterns and is not compatible with ASCII.

Змінено в версії 3.7: Compiled regular expression objects with the LOCALE flag no longer depend on the locale at compile time. Only the locale at matching time affects the result of matching.

re.M
re.MULTILINE

When specified, the pattern character '^' matches at the beginning of the string and at the beginning of each line (immediately following each newline); and the pattern character '$' matches at the end of the string and at the end of each line (immediately preceding each newline). By default, '^' matches only at the beginning of the string, and '$' only at the end of the string and immediately before the newline (if any) at the end of the string.

Corresponds to the inline flag (?m).

re.NOFLAG

Indicates no flag being applied, the value is 0. This flag may be used as a default value for a function keyword argument or as a base value that will be conditionally ORed with other flags. Example of use as a default value:

def myfunc(text, flag=re.NOFLAG):
    return re.match(text, flag)

Added in version 3.11.

re.S
re.DOTALL

Make the '.' special character match any character at all, including a newline; without this flag, '.' will match anything except a newline.

Corresponds to the inline flag (?s).

re.U
re.UNICODE

In Python 3, Unicode characters are matched by default for str patterns. This flag is therefore redundant with no effect and is only kept for backward compatibility.

See ASCII to restrict matching to ASCII characters instead.

re.X
re.VERBOSE

This flag allows you to write regular expressions that look nicer and are more readable by allowing you to visually separate logical sections of the pattern and add comments. Whitespace within the pattern is ignored, except when in a character class, or when preceded by an unescaped backslash, or within tokens like *?, (?: or (?P<...>. For example, (? : and * ? are not allowed. When a line contains a # that is not in a character class and is not preceded by an unescaped backslash, all characters from the leftmost such # through the end of the line are ignored.

Це означає, що два наступних об’єкти регулярного виразу, які відповідають десятковому числу, функціонально однакові:

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() та інших методів, описаних нижче .

The expression’s behaviour can be modified by specifying a flags value. Values can be any of the flags variables, combined using bitwise OR (the | operator).

Послідовність

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

еквівалентно

result = re.match(pattern, string)

але використання re.compile() і збереження отриманого об’єкта регулярного виразу для повторного використання ефективніше, якщо вираз використовуватиметься кілька разів в одній програмі.

Примітка

Зібрані версії найновіших шаблонів, переданих до re.compile(), і функції відповідності на рівні модуля кешуються, тому програмам, які використовують лише кілька регулярних виразів одночасно, не потрібно турбуватися про компіляцію регулярних виразів.

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

Scan through string looking for the first location where the regular expression pattern produces a match, and return a corresponding Match. Return None if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.

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

If zero or more characters at the beginning of string match the regular expression pattern, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

Зауважте, що навіть у режимі MULTILINE re.match() збігатиметься лише на початку рядка, а не на початку кожного рядка.

Якщо ви хочете знайти збіг будь-де в string, використовуйте натомість search() (див. також search() проти match()).

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

If the whole string matches the regular expression pattern, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

Added in version 3.4.

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

Розділіть рядок на входження шаблону. Якщо в шаблоні використовуються дужки для захоплення, тоді текст усіх груп у шаблоні також повертається як частина результуючого списку. Якщо 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)

Повертає всі неперекриваючі збіги шаблону в рядку у вигляді списку рядків або кортежів. Рядок сканується зліва направо, і збіги повертаються в порядку знайдення. Порожні збіги включаються в результат.

Результат залежить від кількості груп захоплення в шаблоні. Якщо груп немає, поверніть список рядків, які відповідають повному шаблону. Якщо існує рівно одна група, поверніть список рядків, які відповідають цій групі. Якщо присутні кілька груп, поверніть список кортежів рядків, які відповідають групам. Незахоплюючі групи не впливають на форму результату.

>>> 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)

Return an iterator yielding Match objects over all non-overlapping matches for the RE pattern in string. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result.

Змінено в версії 3.7: Непорожні збіги тепер можуть починатися одразу після попереднього порожнього збігу.

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

Повертає рядок, отриманий шляхом заміни крайніх лівих неперекриваючих входжень pattern у string на заміну repl. Якщо шаблон не знайдено, рядок повертається без змін. repl може бути рядком або функцією; якщо це рядок, будь-які вихідні символи зворотної косої риски в ньому обробляються. Тобто \n перетворюється на один символ нового рядка, \r перетворюється на повернення каретки і так далі. Невідомі вихідні коди літер ASCII зарезервовано для майбутнього використання та розглядаються як помилки. Інші невідомі вихідні сигнали, такі як \& залишаються в спокої. Зворотні посилання, такі як \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{'

If repl is a function, it is called for every non-overlapping occurrence of pattern. The function takes a single Match argument, and returns the replacement string. For example:

>>> 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'

The pattern may be a string or a Pattern.

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

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

Змінено в версії 3.1: Додано необов’язковий аргумент flags.

Змінено в версії 3.5: Невідповідні групи замінюються порожнім рядком.

Змінено в версії 3.6: Невідомі вихідні коди в шаблоні, що складаються з '\' і літери ASCII, тепер є помилками.

Змінено в версії 3.7: Невідомі вихідні символи в repl, які складаються з '\' і літери ASCII, тепер є помилками.

Змінено в версії 3.7: Порожні збіги для шаблону замінюються, якщо вони суміжні з попереднім непорожнім збігом.

Змінено в версії 3.12: Group id can only contain ASCII digits. In bytes replacement strings, group name can only contain bytes in the ASCII range (b'\x00'-b'\x7f').

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

Виконайте ту саму операцію, що й sub(), але поверніть кортеж (new_string, number_of_subs_made).

Змінено в версії 3.1: Додано необов’язковий аргумент flags.

Змінено в версії 3.5: Невідповідні групи замінюються порожнім рядком.

re.escape(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

Індекс у шаблоні, де не вдалося компілювати (може бути None).

lineno

Рядок, що відповідає pos (може бути None).

colno

Стовпець, що відповідає pos (може бути None).

Змінено в версії 3.5: Додані додаткові атрибути.

Об’єкти регулярного виразу

class re.Pattern

Compiled regular expression object returned by re.compile().

Змінено в версії 3.9: re.Pattern supports [] to indicate a Unicode (str) or bytes pattern. See Загальний тип псевдоніма.

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

Scan through string looking for the first location where this regular expression produces a match, and return a corresponding Match. Return None if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.

Необов’язковий другий параметр 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]])

If zero or more characters at the beginning of string match this regular expression, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

Необов’язкові параметри 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]])

If the whole string matches this regular expression, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

Необов’язкові параметри 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'>

Added in version 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

The regex matching flags. This is a combination of the flags given to compile(), any (?...) inline flags in the pattern, and implicit flags such as UNICODE if the pattern is a Unicode string.

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 object returned by successful matches and searches.

Змінено в версії 3.9: re.Match supports [] to indicate a Unicode (str) or bytes match. See Загальний тип псевдоніма.

Match.expand(template)

Return the string obtained by doing backslash substitution on the template string template, as done by the sub() method. Escapes such as \n are converted to the appropriate characters, and numeric backreferences (\1, \2) and named backreferences (\g<1>, \g<name>) are replaced by the contents of the corresponding group. The backreference \g<0> will be replaced by the entire match.

Змінено в версії 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'

Named groups are supported as well:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton")
>>> m['first_name']
'Isaac'
>>> m['last_name']
'Newton'

Added in version 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 за замовчуванням дорівнює нулю (це означає весь відповідний підрядок). Повертає -1, якщо група існує, але не брала участі в матчі. Для об’єкта збігу 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 поверніть 2-кортеж (m.start(group), m.end(group)). Зауважте, що якщо група не брала участі в матчі, це (-1, -1). група за замовчуванням дорівнює нулю, весь збіг.

Match.pos

Значення pos, яке було передано в метод search() або match() об’єкта regex. Це індекс у рядку, за яким механізм RE почав шукати збіг.

Match.endpos

Значення endpos, яке було передано в метод search() або match() об’єкта regex. Це індекс у рядку, за який механізм RE не виходить.

Match.lastindex

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

Match.lastgroup

Ім’я останньої відповідної групи захоплення або None, якщо група не мала назви, або якщо жодна група не була знайдена взагалі.

Match.re

Об’єкт регулярного виразу, чий метод match() або search() створив цей екземпляр відповідності.

Match.string

Рядок передається до 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 does not currently have an equivalent to scanf(). Regular expressions are generally more powerful, though also more verbose, than scanf() format strings. The table below offers some more-or-less equivalent mappings between scanf() format tokens and regular expressions.

scanf() Token

Регулярний вираз

%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

you would use a scanf() format like

%s - %d errors, %d warnings

Еквівалентним регулярним виразом буде:

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

search() проти match()

Python offers different primitive operations based on regular expressions:

  • re.match() checks for a match only at the beginning of the string

  • re.search() checks for a match anywhere in the string (this is what Perl does by default)

  • re.fullmatch() checks for entire string to be a match

Наприклад:

>>> 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']

Знайти всі прислівники та їх позиції

If one wants more information about all matches of a pattern than the matched text, finditer() is useful as it provides Match objects instead of strings. Continuing with the previous example, if a writer wanted to find all of the adverbs and their positions in some text, they would use finditer() in the following manner:

>>> 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"текст") зберігає регулярні вирази нормальними. Без нього кожен зворотний слеш ('\') у регулярному виразі повинен був би мати префікс іншим, щоб уникнути його. Наприклад, два наступних рядки коду функціонально ідентичні:

>>> 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)
[Frie09]

Фрідл, Джеффрі. Освоєння регулярних виразів. 3rd ed., O’Reilly Media, 2009. Третє видання книги більше не охоплює Python взагалі, але перше видання охоплювало написання хороших шаблонів регулярних виразів дуже детально.