Синтаксис регулярных выражений в Python.
Поведение и применение символов регулярных выражений.
Синтаксис регулярных выражений в Python немного отличается от синтаксиса регулярных выражений в языке программирования PERL.
Регулярные выражения могут быть объединены для формирования новых регулярных выражений. Если A и B являются регулярными выражениями, то AB также является регулярным выражением. В общем, если строка p соответствует A , а другая строка q соответствует B , строка pq будет соответствовать AB . Это верно, если только A или B не содержат операций с низким приоритетом — граничные условия между А и В или пронумерованные ссылки на группы. Таким образом, сложные выражения могут быть легко построены из более простых примитивных выражений.
Регулярные выражения могут содержать как специальные, так и обычные символы. Большинство обычных символов, таких как 'A' , 'a' или '0' , являются простейшими регулярными выражениями, они просто соответствуют друг другу. Вы можете объединять обычные символы, поэтому выражение last соответствует строке 'last' .
Некоторые символы, такие как '|' или '(' , являются специальными. Специальные символы либо обозначают классы обычных символов, либо влияют на интерпретацию регулярных выражений вокруг них.
Классификаторы, которые осуществляют повтор символов или группы символов '*' , '+' , '?' ,
Содержание:
-
,
- '.' — любой символ;
- '^' — началу строки;
- '$' — конец строки;
- '*' — 0 или более повторений;
- '+' — 1 или более повторений;
- '?' — 0 или 1 повторений;
- '*?' , '+?' , '??' — ограничение жадности;
- '
' — m повторений; - '
' — как можно больше повторений в промежутке от m до n ; - '
?' — как можно меньше повторений в промежутке от m до n ; - '\' — экранирование специальных символов;
- '[]' — символьный класс;
- '|' — или;
- '(. )' — группа с захватом;
- '(?aiLmsux)' — установка флагов регулярного выражения;
- '(?aiLmsux-imsx. )' — установка и удаление флагов;
- '(. )' — группа без захвата;
- '(?P<name>. )' — именованная группа;
- '(?P=name)' — обратная ссылка на именованную группу;
- '(?#. )' — комментарий;
- '(?=. )' — опережающая позитивная проверка;
- '(. )' — опережающая негативная проверка;
- '(?<=. )' — позитивная ретроспективная проверка;
- '(?<. )' — негативная ретроспективная проверка;
- '(?(id/name)yes-pattern|no-pattern)' — стараться соответствовать yes-pattern ;
- '\number' — соответствие группы с тем же номером;
- '\A' — только с начало строки;
- '\b' — пустая строка (начало или конц слова);
- '\B' — пустая строка (НЕ начало или конец слова);
- '\d' — любая десятичная цифра;
- '\D' — НЕ десятичная цифра;
- '\s' — пробельный символ;
- '\S' — НЕ пробельный символ;
- '\w' — символы, которые могут быть частью слова;
- '\W' — символы, которые НЕ могут быть частью слова;
- '\Z' — только с конец строки;
- В символьном классе, символы могут быть перечислены по отдельности, например выражение [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 в неоднозначных случаях. Эти случаи включают символьные классы, начинающиеся с литерала '[' или содержащие последовательности буквенных символов '—' , '&&' , '
- re.A — сопоставление только в ASCII,
- re.I — игнорирование регистра,
- re.L — в зависимости от локали,
- re.M — многострочный,
- re.S — точка соответствует всем,
- re.U — сопоставление в Юникоде
- re.X — режим отладки.
- re.A — сопоставление только в ASCII,
- re.I — игнорирование регистра,
- re.L — в зависимости от локали,
- re.M — многострочный,
- re.S — точка соответствует всем,
- re.U — сопоставление в Юникоде
- re.X — режим отладки.
- \d: цифровой символ от 0 до 9;
- \D: любой нецифровой символ;
- \s: пробельный символ;
- \S: любой непробельный символ;
- \w: любой символ;
- \W: любой не цифро-буквенный символ;
- \b: определяет границы слова;
- . : обозначает любой символ; (пример)
- \. : соответствует точке.
- <>: группировка числовых значений. Например, \d <3>дает совпадения, включающие 3 цифры, а \d <3,5>— совпадения, содержащие от 3 до 5 цифр. По сути, это
. - []: группировка символов. Соответствует одному из символов в скобках. Например, [a-z] выдаст совпадения с каждым символом алфавита в нижнем регистре.
- +: соответствует предыдущему элементу один или более раз. Например, [a-z]+a сгруппирует результат совпадений, как показано в примере.
- ?: соответствует предыдущему элементу 0 или один раз. Здесь можно посмотреть принцип действия [a-z]?a .
- *: соответствует предыдущему элементу 0 или множество раз. Обратимся к примеру [a-z]*a .
- $: означает конец строки.
- ^: указывает на начало строки.
- |: оператор или. Например, col(o|u)r соответствует и американскому, и британскому вариантам написания слова color.
- парсинг входных данных, например текста, логов, веб-информации и т.д.;
- валидация пользовательского ввода;
- тестирование результатов вывода;
- поиск текста;
- реструктуризация данных.
- Позитивная опережающая проверка. Она проводится с использованием в строке символов ?= . Например, xyz(?=abc) предварительно просматривает все xyz , проверяя наличие abc и выявляя соответствия только при его обнаружении (Пример).
- Негативная опережающая проверка. Аналогична предыдущей, но с помощью утверждения ?! выполняющая противоположную задачу. В этом случае xyz(?!abc) предварительно просматривает все xyz , проверяя отсутствие abc , и выдает совпадения соответственно результатам (Пример).
- Позитивная ретроспективная проверка. В данной ситуации движок регулярных выражений временно работает в обратном направлении. (?<=abc)xyz ищет все xyz , которым предшествует abc , а именно справа налево (Пример).
- Негативная ретроспективная проверка похожа на предыдущий вариант, но (?<!abc)xyz уже ищет все xyz , которым не предшествует abc , а именно справа налево (Пример).
- строчными буквами: (?=.*[a-z]) ;
- цифрами: (?=.*\d) ;
- специальными символами: (?=.*_@$!%*?&) .
- \ d = соответствует цифрам (числовым символам) в строке;
- \ D = соответствует чему угодно, кроме цифры;
- \ s = соответствует пробелу (например, пробел, TAB и т. д.);
- \ S = соответствует чему угодно, кроме пробела;
- \ w = соответствует буквам или цифрам алфавита;
- \ W = соответствует чему угодно, кроме буквы;
- \ b = соответствует любому символу, который может разделять слова (например, пробел, дефис, двоеточие и т. д.);
- . = соответствует любому символу, кроме новой строки. Следовательно, он называется оператором с подстановочными знаками. Таким образом, «. *» будет соответствовать любому символу, любое количество раз.
Специальные символы:
— '.' — точка:
В режиме по умолчанию '.' соответствует любому символу, кроме новой строки. Если указан флаг 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>' .
Конструкция '
Конструкция '
Конструкция '
Специальный символ '\' либо экранирует специальные символы, разрешающие соответствовать символам, таким как '*' , '?' и так далее или сигнализирует о специальной последовательности, которые будут обсуждаются ниже.
Если не использовать необработанную строку r'' в написании шаблона регулярного выражения, то необходимо помнить, что Python также использует обратную косую черту в качестве escape-последовательности в строковых литералах. Если escape-последовательность не распознается синтаксическим анализатором Python, обратная косая черта и последующий символ включаются в полученную строку. Если Python распознает полученную последовательность, обратный слеш должен повторяться дважды. Это сложно и трудно понять, поэтому настоятельно рекомендуется использовать необработанные строки r'' для всех, кроме самых простых регулярных выражений.
Конструкция '[]' используется для обозначения символьного класса:
Выражение A|B , где A и B могут быть произвольными регулярными выражениями, создает выражение, которое будет соответствовать либо A , либо B . Таким образом '|' может быть разделено произвольное число регулярных выражений. Это можно использовать и внутри групп. При сканировании строки, регулярные выражения разделенные символом '|' проверяют совпадения слева направо. Когда один из шаблонов полностью совпадает, эта ветвь принимается. Это означает, что если A совпало, то B не будет проверяться дальше, даже если это приведет к более длительному общему соответствию. Другими словами, оператор ' | ' никогда не бывает жадным.
Чтобы сопоставить литерал '|' , используйте \| или заключите его в символьный класс, как [|] .
Конструкция '(. )' соответствует любому регулярному выражению, заключенному в скобки и указывает начало и конец группы. Содержимое группы может быть получено после выполнения поиска совпадений, а так же в строке шаблона с ней может быть сопоставлена обратная ссылка вида \number , описанной ниже. Чтобы сопоставить литералы '(' или ')' используйте \( или \) , или заключите их в символьный класс: [(] , [)] .
Расширения регулярных выражений:
Конструкция '(. )' обозначает расширение регулярных выражений (в противном случае '?' после '(' не имеет смысла. Первый символ после '?' определяет, в чем смысл и дальнейший синтаксис конструкции. Расширения обычно не создают новую группу, за исключением конструкции (?P<name>. ) — единственное исключение из этого правила. Ниже приведены поддерживаемые в настоящее время расширения регулярных выражений.
— '(?aiLmsux)'
Конструкция '(?aiLmsux)' обозначает один или несколько букв из набора 'a' , 'i' , 'L' , 'm' , 's' , 'u' , 'x' . Группа соответствует пустой строке. Буквы устанавливают соответствующие флаги:
Флаги описаны в разделе "Флаги регулярных выражений в Python". Конструкция полезна, если необходимо включить флаги как часть регулярного выражения вместо передачи аргумента флага в функцию re.compile() . Флаги должны использоваться первыми в строке шаблона регулярного выражения.
Конструкция '(. )' обозначает группу без захвата. Соответствует любому регулярному выражению, заключенному в круглые скобки, но подстрока, сопоставленная такой группой не может быть получена после выполнения сопоставления, так же в шаблоне на нее не может быть поставлена обратная ссылка типа \number .
— '(?aiLmsux-imsx. )'
Конструкция '(?aiLmsux-imsx. )' обозначает ноль или более букв из набора 'a' , 'i' , 'L' , 'm' , 's' , 'u' , 'x' , необязательно с последующим '-' , за которым следует одна или более букв из 'i' , 'm' , 's' , 'x' . Буквы устанавливают или удаляют соответствующие флаги:
При использовании в качестве встроенных флагов 'a' , 'L' и 'u' являются взаимоисключающими, поэтому они не могут быть объединены или следовать за '-' . Вместо этого, когда один из них появляется во встроенной группе, он переопределяет соответствующий режим во включающей группе. В шаблонах Unicode (?a. ) переключается на сопоставление только ASCII, и (?u. ) на сопоставление Unicode (по умолчанию). В байтовом шаблоне (?L. ) переключается на соответствие в зависимости от локали и (?a. ) переключается на соответствие только ASCII ( по умолчанию). Это переопределение действует только для узкой встроенной группы и исходный режим сопоставления восстанавливается вне группы.
— '(?P<name>. )'
Конструкция '(?P<name>. )' называется именованной группой, работает аналогично обычной группе (. ) . Совпавшая подстрока захватывается этой группой и доступна для последующего извлечения через символическое имя группы name . В шаблоне регулярного выражения имена групп должны быть действительными идентификаторами Python и каждое имя группы должно быть определено только один раз. Именованная группа также является пронумерованной группой, как если бы она была простой группой.
— '(?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() :
Этот пример ищет слово после дефиса:
Конструкция '(?<. )' называется негативной ретроспективной проверкой, где . регулярное выражение, которое определяет проверяемую позицию слева от основного выражения. Подобно положительным проверкам, шаблон регулярного выражения должен соответствовать только строкам фиксированной длины. Шаблоны регулярных выражений, которые начинаются с негативной ретроспективной проверки могут совпадать в начале искомой строки.
— '(?(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>' .
Специальные последовательности:
Специальные последовательности состоят из '\' и символа из списка ниже. Если обычный символ не является цифрой ASCII или буквой ASCII, то результирующее регулярное выражение будет соответствовать второму символу. Например \$ соответствует символу '$' .
— '\number'
Специальная последовательность '\number' соответствует содержимому группы с тем же номером. Группы нумеруются начиная с 1. Например выражение (.+ ) \1 соответствует 'the the' или '55 55' , но не 'thethe' , обратите внимание на пробел после группы. Эта специальная последовательность может быть использована только для сопоставления одной из первых 99 групп. Если первая цифра числа равна 0, или число имеет длину 3 восьмеричные цифры, то оно будет интерпретироваться как символ с восьмеричным значением числа. Внутри '[' и ']' символьного класса все числовые эскейпы рассматриваются как символы.
Специальная последовательность '\A' совпадает только с положением начала строки.
Специальная последовательность '\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' соответствует пустой строке, но только если она не находится в начале или конце слова. Это означает, что выражение r'py\B' покажет совпадение в строках 'python' , 'py3' , 'py2' , но не 'py' , 'py.' , или 'py!' . Последовательность \B — это как раз противоположность \b , поэтому символы слов в шаблонах Unicode являются буквенно-цифровыми символами Unicode или подчеркиванием, хотя это может быть изменено с помощью флага ASCII. Границы слов определяются текущей локализацией, если используется флаг локали LOCALE .
Для шаблонов строк Unicode: специальная последовательность '\d' соответствует любой десятичной цифре Unicode, то есть любому символу в категории символов Unicode [Nd] . Это включает в себя диапазон [0-9] , а также много других цифровых символов. Если используется флаг re.ASCII , то эквивалентно символьному классу [0-9] .
Для шаблонов байтовых строк: специальная последовательность '\d' соответствует любой десятичной цифре, эквивалентно символьному классу [0-9].
Специальная последовательность '\D' соответствует любому символу, который не является десятичной цифрой. Это противоположность \d . Если используется флаг re.ASCII , то '\D' становится эквивалентно символьному классу [^0-9].
Для шаблонов строк Unicode: специальная последовательность '\s' соответствует пробельным символам Unicode, включая и многие другие символы, например неразрывные пробелы, предписанные правилами типографики во многих языках. Если используется флаг re.ASCII , то '\s' совпадает только с символьным классом [ \t\n\r\f\v] .
Для шаблонов байтовых строк: специальная последовательность '\s' соответствует символам, которые считаются пробелами в наборе символов ASCII, что эквивалентно символьному классу [ \t\n\r\f\v] .
Специальная последовательность '\S' соответствует любому символу, который не является пробельным символом. Это противоположность \s . Если используется флаг re.ASCII , то '\S' эквивалентно символьному классу [^ \t\n\r\f\v] .
Для шаблонов строк Unicode: специальная последовательность '\w' соответствует символам Unicode, что включает в себя большинство символов, которые могут быть частью слова на любом языке, а также цифры и подчеркивание. Если используется флаг re.ASCII , то '\w' становится эквивалентно символьному классу [a-zA-Z0-9_] .
Для шаблонов байтовых строк: специальная последовательность '\w' соответствует символам, которые считаются буквенно-цифровыми символами ASCII, что эквивалентно символьному классу [a-zA-Z0-9_] . Если используется флаг re.LOCALE , то '\w' соответствует символам, которые являются буквенно-цифровыми в текущей локали + символ подчеркивания.
Специальная последовательность '\W' соответствует любому символу, который не является символом слова. Это противоположность \w . Если используется флаг re.ASCII , то '\W' становится эквивалентно символьному классу [^a-zA-Z0-9_] . Если используется флаг re.LOCALE , то '\W' соответствует символам, которые НЕ являются буквенно-цифровыми символами в текущей локали + символ подчеркивания.
Специальная последовательность '\Z' совпадает только с положением конца строки.
Большинство стандартных экранирований, поддерживаемых строковыми литералами Python, также принимаются анализатором регулярных выражений:
Обратите внимание, что \b используется для представления границ слов и означает "возврат" только внутри классов символов.
Escape-последовательности '\u' , '\U' и '\N' распознаются только в шаблонах строк Unicode. В шаблонах байтовых строк они являются ошибками. Неизвестные экранированные символы ASCII зарезервированы для будущего использования и рассматриваются как ошибки.
Регулярные выражения в Python: необходимый запас знаний

Регулярные выражения представляют собой последовательность знаков и символов, которые в глазах неподготовленного человека выглядят также устрашающе, как и уличные вывески на иностранном языке. С этой точки зрения, нельзя не заметить иронию в самом термине “регулярные выражения”.
Любой ценой я избегал с ними встречи, и эта игра в прятки затянулась намного дольше, чем можно себе представить. Но однажды я решил, что пора с ними подружиться.
Регулярные выражения — это чрезвычайно важная часть деятельности программиста и полезный инструмент в рабочем арсенале. Они избавляют от необходимости часами сидеть за написанием неоправданно длинного кода.
Вот почему я погрузился в волшебный мир регулярных выражений в ожидании сложных испытаний, но стоило лишь разобраться с базовыми принципами, как дальнейший путь по дороге из желтого кирпича стал вполне приемлемым.
Работа с регулярными выражениями напоминает изучение иностранного языка: как только приходит понимание слов и грамматики — начинаешь без труда составлять предложения.
В самом общем смысле регулярные выражения — это последовательности символов для поиска соответствий шаблону. Они являются экземплярами регулярного языка и широко применяются для парсинга текста или валидации входных строк.
Представьте лист картона, в котором вырезаны определенные фигуры. И только фигуры, точь-в-точь соответствующие вырезам, смогут через них пройти. В данном случае лист картона аналогичен строке регулярного выражения.

Как выглядел бы поисковый шаблон с регулярным выражением для рассмотренного примера?
Инструкция ввода задает три входящие фигуры: круг, треугольник и прямоугольник.
Движок регулярного выражения обнаружит совпадения только слов circle и triangle . На сервисе Regex101 вы можете сами в этом убедиться.
Сами по себе регулярные выражения являются неотъемлемой частью регулярного языка. Однако их поддерживают большинство актуальных языков программирования, которые располагают встроенными (или доступными для скачивания) модулями.
Таким образом, появляется возможность использовать их в наших рабочих языках. Помимо ссылок на regex101, встречающихся по ходу статьи, во всех примерах кода будет применяться модуль регулярных выражений Python re .
Как же переложить на код этот метафорический образ листа картона? Обратимся к примеру.
Дана строка “Sylvie is 20 years old” (“Сильвии 20 лет”), и нужно извлечь из предложения только возраст, т.е. исключительно число. Для этой цели существует шаблон регулярного выражения \d — специальный символ, который соответствует только шаблонам, содержащим цифры (подробным разбором займемся позже).


Не совсем то, что нужно, но первый шаг навстречу цели уже сделан. По крайней мере, цифры обнаружены! Их распознал блок, вырезанный из красного картона.
В зависимости от условия он может в буквальном смысле варьироваться от одного буквенного символа алфавита (например, регулярное выражение a что ни на есть верное и предназначено для поиска a внутри строкового ввода) до группы специальных символов. Как мы увидим далее, они представлены в большом разнообразии.
Однако требуется получить не отдельные цифры, а целое число. Немного преобразуем используемый идентификатор с помощью другого блока.


Отлично! Мы получили возраст Сильвии из строки! Стоп, а если бы в ней также был указан год рождения? При использовании вышеприведенного выражения результатом стали бы все двузначные варианты чисел в предложении.
Поскольку это не входит в наши планы, то подумаем о внесении дальнейших изменений.
Добавляем граничное выражение, поскольку требуемое двузначное число окружено с обеих сторон пробелами.


Мы получаем нужный результат, даже при наличии в строке четырехзначного числа. Ради интереса можете проверить действие ранее рассмотренных строк регулярных выражений:
Довольно аккуратно, не так ли? С помощью минимального однострочного кода мы извлекли число из строки.
Как уже ранее упоминалось, существует множество символов для создания в коде виртуальных аналогов таких вырезанных блоков. Пора с ними познакомиться.
Символы
Модификаторы
Это был перечень самых распространенных модификаторов. Они понадобятся как для изучения данной статьи, так и в большинстве практических случаев. Однако расширенная шпаргалка с указанием других классов символов никогда не помешает.
Помимо знания символов также следует разобраться в основных принципах работы движка регулярных выражений. Тогда столкнувшись с непредвиденным результатом сложных случаев, вы уже не будете бесконечно долго теряться в догадках.
Принцип работы регулярных выражений
Существует 2 типа движков regex : первые ориентированы на текст, а вторые, наиболее распространенные, — на регулярные выражения. Вполне возможно, что вы с ними то как раз и работаете. Проведем простой тест с помощью Python для проверки используемого типа:

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

Как видим, поиск совпадений происходит слева направо. Освоение этих азов определенно поможет в дальнейшей работе.
А теперь, вооружившись новыми знаниями, применим их на практике. Перечислим несколько случаев применения регулярных выражений:
Однако учиться лучше всего на примерах. Теперь, когда мы знаем принципы действия регулярных выражений и значения символов рассекречены, рассмотрим 3 конкретных ситуации их использования с помощью нескольких строк кода.
Пример 1. Валидация адресов электронной почты
В любом руководстве по регулярным выражениям данный пример встречается по умолчанию. Он представляет собой аналог “Hello World”, поэтому ему суждено быть в этом разделе. Его задача — проверять форматы вводимых адресов электронной почты.
Пошагово рассмотрим решение задачи. Во-первых, мы (зачастую) знаем, как выглядят корректные адреса e-mail:
Имя пользователя или someone обычно состоит из букв алфавита или комбинации цифр. Иногда могут встречаться и специальные символы, но новичкам в мире регулярных выражений лучше начать с простого примера.
Итак, у нас есть символы от a до z, цифры от 0 до 9, а также заглавные буквы в диапазоне A-Z. Регулярное выражение данной группы выглядит следующим образом:
Аналогично, служба электронной почты обычно имеет буквенное обозначение, например Gmail, gmx, Hotmail, и следует за знаком @. Следовательно:
На завершающем этапе рассмотрим наиболее известные домены — com, net, edu и org — которые указываются после знака точки вслед за провайдером службы электронной почты.
Объединяя все вместе, получаем регулярное выражение:
Теперь применим его в скрипте Python, который принимает на входе id электронной почты и проверяет его на соответствие требованиям формата.
Полученный результат выглядит следующим образом:
Теперь вы стали обладателем своего собственного валидатора id электронной почты.
Пример 2. Извлечение имен и значений возраста из текста
Ранее уже был рассмотрен упрощенный пример получения возраста из строки. В этом разделе научимся извлекать имена/текст и вносить их в словарь.
Нам уже известно, как с помощью регулярного выражения \b\d<2>\b извлечь двузначное число из строки. В случае с текстом в данном примере поработаем с 2 или 3 цифрами (из-за присутствия величины, обозначающей столетие).
Что касается процедуры получения имен из текста, то, как видим, каждое из них состоит из более 3 букв. В связи с этим, с задачей должны справиться группы строк с заглавными буквами длиной в 3 и более символов:
Для итоговой операции по составлению словаря, в котором имена людей соответствуют их возрастам, как нельзя кстати подойдет простое грамматическое правило английского языка: в структуре предложения возраст всегда следует за именем.

Конечно же, по мере усложнения входного текста и необходимости извлечения большего объема информации более рациональным путем, придется прибегать к дополнительным средствам помимо регулярных выражений. Однако могу вас заверить, что даже в сложных случаях этот инструмент обязательно пригодится в той или иной степени для упрощения.
Пример 3. Сопоставление пароля с шаблоном
Большинство из вас наверняка встречали такое предложение при создании нового пароля:
“Для гарантии надежности пароль должен состоять как минимум из 8 символов, в число которых должны входить, по крайней мере, по одной заглавной и строчной букве, цифре и одному специальному символу”.
Когда-нибудь интересовались, как это сделать? Конечно, с помощью регулярных выражений. Данный пример немного посложнее, чем предыдущие, и включает ряд понятий, с которыми будем знакомиться в процессе. А затем, вооружившись ими, вы сами сможете создать простую версию.
Одна из частей задачи не вызывает сложности, так как основана на ранее изученном материале. Потребуются символы (верхнего и нижнего регистров) — A-Z и a-z , цифры — \d и специальные символы — _@$!%*?& , которые в сумме составляют строку длинной более 8 единиц:
Это гарантирует совпадения со всеми вариантами, включающими любые из перечисленных выше символов.
Например, asdf@1234 станет верным паролем даже без заглавной буквы. Пример.
Нужен метод, предварительно сопоставляющий и выявляющий хотя бы одно соответствие из каждой группы. Речь идет о позиционной проверке в регулярных выражениях. Она сопоставляет символы без указания конкретных совпадений. Вместо этого возвращается двоичный результат о наличии или отсутствии совпадение. Следовательно, по факту они являются утверждениями.
Позиционная проверка бывает двух типов:
Опережающая
Ретроспективная
С учетом изученных понятий мы можем создать регулярное выражение для второй части задачи с паролем, и лучше всего подойдет позитивная опережающая проверка.
Рассмотрим все поэтапно. Для соответствия опережающей проверке необходимы заглавные буквы.
(?=[A-Z]) соотнесет заглавные буквы при предварительном просмотре и выдаст многочисленные совпадения по мере их обнаружения. Поскольку такие совпадения должны быть в любом месте строки, то преобразуем регулярное выражение в (?=.*[A-Z]) .
Таким же образом поступим со
Объединяем все вместе между начальным и конечным идентификаторами строки (соответственно ^ и $):
Согласитесь, что сейчас все становится намного понятнее. Теперь реализуем простой инструмент проверки надежности пароля с помощью данного регулярного выражения:
Результат выглядит следующим образом (с паролями abcABC@1234 и abcABC1234):
Регулярные выражения в Python
В этой статье мы рассмотрим важный, простой и мощный инструмент специалиста по данным – регулярное выражение. Мы узнаем о регулярных выражениях и о том, как их использовать в скриптах Python для обработки текстовых данных.
Текст – одна из основных форм данных, и люди используют текст для общения и самовыражения, например, в веб-страницах, сообщениях в блогах, документах, каналах Twitter, RSS и т.д. Вот где регулярные выражения удобны и эффективны.
Будь то фильтрация данных с веб-страниц, анализ данных или интеллектуальный анализ текста – регулярные выражения являются предпочтительным инструментом для выполнения этих задач. Регулярные выражения упрощают задачи обработки текста, такие как (NLP), тем самым сокращая усилия, время и ошибки, которые неизбежно возникают при написании ручных сценариев.
Что такое регулярное выражение в Python?
Регулярное выражение в Python – это последовательность символов, описывающая текстовые шаблоны. Используя регулярные выражения, мы можем сопоставлять входные данные с определенными шаблонами (например, поиск), извлекать совпадающие строки (фильтрация, разделение), а также заменять вхождения шаблонов подстановками, и все это с минимальным объемом кода.
Большинство языков программирования имеют встроенную поддержку для определения и работы с регулярными выражениями. Perl, Python, Java – некоторые известные языки программирования с первоклассной поддержкой регулярных выражений.
Стандартные библиотечные функции в таких языках программирования обеспечивают высокопроизводительные, надежные и (почти) безошибочные реализации операций с регулярными выражениями (поиск, фильтрация и т.д.), что упрощает быстрое создание высококачественных приложений, эффективно обрабатывающих текст. .
Python предоставляет встроенный модуль re для работы с регулярными выражениями. Чтобы импортировать пакет Python re, используйте:
Пакет re предоставляет набор методов для выполнения общих операций с использованием регулярных выражений.
Поиск шаблонов в строке
Одна из наиболее распространенных задач при обработке текста – это поиск, содержит ли строка определенный шаблон или нет. Например, вы можете захотеть выполнить операцию над строкой при условии, что строка содержит число. Или вы можете проверить пароль, убедившись, что он содержит числа и специальные символы. Операция «сопоставления» RE предоставляет эту возможность.
Python предлагает две примитивные операции, основанные на регулярных выражениях: функция re.match() проверяет соответствие шаблону в начале строки, тогда как re.search() проверяет соответствие шаблону в любом месте строки. Давайте посмотрим, как можно использовать эти функции:
Функция re.match()
Функция re.match() проверяет, совпадает ли RE с началом строки. Например, инициализируйте переменную «текст» некоторым текстом, как показано ниже:
Давайте напишем простое регулярное выражение, которое соответствует строке любой длины, содержащей что-либо, если она начинается с буквы C:
А пока давайте не будем беспокоиться о том, как интерпретируется приведенное выше объявление, и предположим, что приведенный выше оператор создает переменную с именем regex, которая соответствует строкам, начинающимся с C.
Мы можем проверить, соответствуют ли строки в тексте регулярному выражению, как показано ниже:
Вперед и запустите этот код. Ниже приведен снимок экрана сеанса Python с запущенным этим кодом.

Первая строка соответствует этому регулярному выражению, поскольку в статистике используется символ «C», тогда как вторая строка начинается с символа «R» и не соответствует регулярному выражению. Функция `match` возвращает объект _sre.SRE_Match, если совпадение найдено, иначе она возвращает None.
В Python регулярные выражения указываются, как необработанные строковые литералы. Необработанный строковый литерал имеет префикс r, за которым сразу следует строковый литерал в кавычках.
В отличие от обычных строковых литералов, Python не интерпретирует специальные символы, такие как ‘\’ внутри необработанных строковых литералов. Это важно и необходимо, поскольку специальные символы имеют другое значение в синтаксисе регулярных выражений, чем то, что они делают в стандартных строковых литералах Python.
Как только совпадение найдено, мы можем получить часть строки, которая соответствует шаблону, используя метод group() для возвращенного объекта соответствия. Мы можем получить всю соответствующую строку, передав 0 в качестве аргумента.
Строительные блоки регулярных выражений
В этом разделе мы рассмотрим элементы, составляющие регулярное выражение, и то, как создаются регулярные выражения.
Регулярное выражение содержит группы, и каждая группа содержит различные спецификаторы, такие как классы символов, повторители, идентификаторы и т.д. Спецификаторы – это строки, которые соответствуют определенным типам шаблона и имеют свой собственный формат для описания желаемого шаблона. Давайте посмотрим на общие спецификаторы.
Идентификаторы
Идентификатор соответствует подмножеству символов, например строчным буквам, числовым цифрам, пробелам и т.д. Regex предоставляет список удобных идентификаторов для соответствия различным подмножествам. Некоторые часто используемые идентификаторы:
Примечание. В приведенном выше примере регулярного выражения и во всех других в этом разделе мы опускаем ведущую букву r в строковом литерале регулярного выражения для удобства чтения. Любой приведенный здесь литерал должен быть объявлен как необработанный строковый литерал при использовании в коде Python.
Повторители
Повторитель используется для указания одного или нескольких экземпляров группы. Ниже приведены некоторые часто используемые повторители.
Оператор звездочка указывает 0 или более повторений предыдущего элемента, насколько это возможно. «ab *» будет соответствовать «a», «ab», «abb» или «a», за которым следует любое количество b.
Оператор «плюс» указывает на 1 или более повторений предыдущего элемента, насколько это возможно. ‘ab +’ будет соответствовать ‘a’, ‘ab’, ‘abb’ или ‘a’, за которым следует как минимум 1 вхождение ‘b’; он не будет соответствовать «а».
Этот символ указывает, что предыдущий элемент встречается не более одного раза, т.е. он может присутствовать или не присутствовать в строке для сопоставления. Например, «ab +» будет соответствовать «a» и «ab».
Фигурные скобки указывают, что предыдущий элемент должен быть сопоставлен ровно n раз. b <4>будет соответствовать ровно четырем символам ‘b’, но не более или менее 4.
Символы *, + ,? и <> называются повторителями, поскольку они определяют, сколько раз повторяется предыдущий элемент.
Разные спецификаторы
Квадратные скобки соответствуют любому заключенному в них одиночному символу. Например, [aeiou] будет соответствовать любой из строчных гласных, а [az] будет соответствовать любому символу от az (с учетом регистра). Это также называется классом символов.
Вертикальная черта используется для разделения альтернатив. photo | foto соответствует либо «фото», либо «фото».
Символ каретки указывает позицию совпадения в начале строки, за исключением случаев, когда он используется внутри квадратных скобок. Например, «^ I» будет соответствовать строке, начинающейся с «I», но не будет соответствовать строкам, у которых нет «I» в начале. По сути, это то же самое, что и функциональность, предоставляемая функцией re.match и функцией re.search.
При использовании в качестве первого символа внутри класса символов он инвертирует соответствующий набор символов для класса символов. Например, «[^ aeiou]» будет соответствовать любому символу, кроме a, e, i, o или u.
Символ доллара указывает позицию совпадения в конце строки.
Круглые скобки используются для группировки различных символов RE, чтобы они действовали как единый блок. ([az] \ d +) будет соответствовать шаблонам, содержащим az, за которым следует любая цифра. Все совпадение рассматривается как группа и может быть извлечено из строки.
Типичные варианты использования регулярных выражений
Теперь мы обсудили строительные блоки написания RE. Давайте поработаем над написанием регулярных выражений.
Возвращение к функции re.match()
Можно сопоставить буквы, как в верхнем, так и в нижнем регистре, с помощью функции сопоставления.
Вышеупомянутое регулярное выражение соответствует первому слову, найденному в строке. Оператор `+` указывает, что строка должна содержать хотя бы один символ.
Как видите, регулярное выражение соответствует первому слову, найденному в строке. После слова «The» стоит пробел, который не рассматривается как буква. Таким образом, сопоставление прекращается, и функция возвращает только первое найденное совпадение. Скажем, строка начинается с числа. В этом случае функция match() возвращает нулевое значение, хотя в строке есть буквы, следующие за числом. Например:
Вышеупомянутое регулярное выражение возвращает null, поскольку функция сопоставления возвращает только первый элемент в строке. Хотя строка содержит алфавиты, ей предшествует число. Следовательно, функция match() возвращает значение null. Этой проблемы можно избежать с помощью функции search().
Функция re.search()
Функция search() соответствует указанному шаблону в строке, аналогично функции match(). Разница в том, что функция search() соответствует шаблону глобально, в отличие от поиска только первого элемента строки. Давайте попробуем тот же пример, используя функцию search().
Это связано с тем, что функция search() возвращает совпадение, хотя строка не начинается с алфавита, но находится в другом месте строки.
Соответствие строк от начала и до конца
Мы можем использовать регулярное выражение, чтобы определить, начинается ли строка с определенного шаблона, используя оператор каретки ^. Аналогичным образом, оператор $ используется для сопоставления, если строка заканчивается заданным шаблоном. Напишем регулярное выражение, чтобы понять это:
Функция re.sub()
Мы изучили использование регулярных выражений для поиска шаблона в строке. Давайте продолжим, чтобы найти, как подставить текст в строку. Для этого мы используем функцию sub(). Она ищет в строке определенный шаблон и заменяет его новым шаблоном.
Как видите, первый параметр функции sub() – это регулярное выражение, которое ищет шаблон для замены. Второй параметр содержит новый текст, который вы хотите заменить на старый. Третий параметр – это строка, над которой выполняется «вспомогательная» операция.
Написание регулярных выражений с идентификаторами
Давайте разберемся с использованием регулярного выражения, содержащего идентификаторы, на примере. Чтобы удалить цифры в строке, мы используем следующее регулярное выражение:
Приведенный выше сценарий находит цифры в строке с помощью идентификатора «\ d» и заменяет его пустой строкой.
Разделение строки
Пакет re предоставляет функцию split() для разделения строк. Эта функция возвращает список разделенных токенов. Например, следующая функция «split» разбивает строку слов при обнаружении запятой:
Функция re.findall()
Функция findall() возвращает список, содержащий все совпавшие высказывания в строке.
Напишем скрипт для поиска типа домена из списка идентификаторов электронной почты, реализующего функцию findall():