Главная страница

Программирование на Python 3. Руководство издательство СимволПлюс


Скачать 3.74 Mb.
НазваниеРуководство издательство СимволПлюс
Дата10.11.2022
Размер3.74 Mb.
Формат файлаpdf
Имя файлаПрограммирование на Python 3.pdf
ТипРуководство
#780382
страница61 из 74
1   ...   57   58   59   60   61   62   63   64   ...   74

Проверка: проверка соответствия фрагментов текста некоторым критериям, например, наличие символа обозначения валюты и по
следующих за ним цифр.

Поиск: поиск подстрок, которые могут иметь несколько форм, на
пример, поиск подстрок «pet.png», «pet.jpg», «pet.jpeg» или
«pet.svg», чтобы при этом не обнаруживались подстроки «car
pet.png» и подобные ей.

Поиск и замена: замена всего, что совпадает с регулярным выраже
нием, и замена на указанную строку, например, поиск подстроки
1
Существует превосходная книга о регулярных выражениях: Jeffrey
E. F. Friedl «Mastering Regular Expressions» (Джеффри Фридл «Регуляр
ные выражения», 3е издание. – Пер. с англ. – СПб.: СимволПлюс, 2008).
Она не имеет явного отношения к языку Python, но модуль re, входящий в состав Python, предлагает функциональность, во многом похожую на ту,
что предлагается механизмом регулярных выражений языка Perl, кото
рый подробно рассматривается в этой книге.

Язык регулярных выражений в Python

Модуль для работы с регулярными выражениями

Язык регулярных выражений в Python
525
«устройство передвижения, движимое мускульной силой» и заме
на подстрокой «велосипед».

Разбиение строк: разбиение строки по точкам совпадения с регу
лярным выражением, например, разбиение строки по подстроке «: »
или «=».
Самым простым выражением является выражение (например, обыч
ный символ), за которым может следовать квантификатор. Более сложные регулярные выражения могут состоять из любого числа вы
ражений с квантификаторами и могут включать проверки и дополни
тельные флаги.
В первом разделе этой главы будут представлены и описаны все ключе
вые концепции, имеющие отношение к регулярным выражениям,
и будет продемонстрирован чистый синтаксис регулярных выражений с минимальными ссылками на язык Python. Затем, во втором разделе,
будет показано, как использовать регулярные выражения в контексте программирования на языке Python, с привлечением сведений из пре
дыдущих разделов. Читатели, знакомые с регулярными выражения
ми и желающие узнать, как они работают в языке Python, могут сразу перейти ко второму разделу (на стр. 538). Глава полностью охватывает язык регулярных выражений, предлагаемый модулем re, включая все проверки и флаги. Мы будем выделять регулярные выражения в тек
сте жирным шрифтом, места совпадений – шрифтом с подчеркиванием, а захва
ченные символы –
Язык регулярных выражений в Python
В этом разделе мы разобьем рассмотрение языка регулярных выраже
ний на четыре подраздела. В первом подразделе демонстрируется, как находить совпадения с отдельными символами или с группами симво
лов, например, совпадение с символом a, или совпадение с символом b,
или совпадение с символом a или b. Во втором подразделе демонстри
руется, как находить совпадения с применением квантификаторов,
например, единственное совпадение, или не менее одного совпадения,
или столько совпадений, сколько вообще возможно. В третьем подраз
деле демонстрируется, как группировать подвыражения и как сохра
нять текст совпадений. И, наконец, в последнем подразделе демонст
рируется, как воздействовать на работу регулярных выражений с ис
пользованием проверок и флагов.
Символы и классы символов
Простейшее регулярное выражение – это обычные литералы симво
лов, такие как a или 5. В отсутствие явного квантификатора такое вы
ражение подразумевает «совпадение с одним вхождением». Напри
мер, регулярное выражение tune состоит из четырех выражений, каж
дое из них неявно определяет одно совпадение, поэтому оно будет сов
с подчеркиванием и затенением

526
Глава 12. Регулярные выражения падать с одним символом t, за которым следует один символ u, за которым следует один символ n, за которым следует один символ e, то есть оно будет совпадать со строками tune и attuned.
Большинство символов могут использоваться как лите
ралы, но некоторые из них имеют «специальное назначе
ние» в языке регулярных выражений и потому должны экранироваться символом обратного слеша (\), когда они используются как литералы. К специальным относятся символы \.^$?+*{}[]()|. В пределах регулярных выраже
ний можно также использовать большинство стандарт
ных экранированных последовательностей языка Py
thon, например, \n – для обозначения символа перевода строки, \t – для обозначения символа табуляции, а так
же экранированные последовательности с шестнадцате
ричными кодами символов \xHH, \uHHHH и \UHHHHHHHH.
Во многих случаях вместо совпадения с единственным символом быва
ет необходимо отыскать совпадение с одним из множества символов.
Реализовать это можно с помощью символьного класса – один или бо
лее символов, заключенные в квадратные скобки. (Символьные клас
сы не имеют никакого отношения к классам в языке Python – это про
сто термин регулярных выражений, используемый для обозначения
«множества символов».) Символьный класс – это выражение и, как и любое другое выражение, в отсутствие явного квантификатора соот
ветствует точно одному символу (который может быть любым симво
лом из данного символьного класса). Например, регулярное выраже
ние r[ea]d совпадает с red и radar, но не со словом read. Точно так же,
чтобы отыскать совпадение с единственной цифрой, можно использо
вать регулярное выражение [0123456789]. Для удобства можно указы
вать диапазон символов с помощью символа дефиса; так, выражение
[0 9]
также будет соответствовать цифре. Имеется возможность инвер
тировать значение символьного класса, указывая символ «крышки»
после открывающей квадратной скобки; так, выражение [^0 9] будет соответствовать любому символу, но не цифре.
Обратите внимание, что в символьном классе все специальные симво
лы, кроме символа \, теряют свое специальное значение, но, что каса
ется символа ^, то он приобретает новое значение (инверсия), когда яв
ляется первым символом в символьном классе; в противном случае он просто обозначает символ «крышки». Кроме того, символ дефиса обо
значает диапазон символов, только если он не является первым симво
лом – в этом случае он просто обозначает символ дефиса.
Так как некоторые наборы символов требуются достаточно часто, для них предусматриваются краткие формы записи – они перечислены в табл. 12.1. За одним исключением, эти сокращенные формы могут использоваться внутри символьных классов, например, регулярное выражение [\dA Fa f] соответствует шестнадцатеричной цифре. Ис
Экранирован
ные последо
вательности, стр. 86

Язык регулярных выражений в Python
527
ключение составляет символ точки, который за пределами символьно
го класса обозначает набор символов, а внутри символьного класса –
сам символ точки.
Таблица 12.1. Сокращенные формы символьных классов
Квантификаторы
Квантификаторы записываются в виде {m,n}, где m и n – это минималь
ное и максимальное число совпадений с выражением, при которых со
ответствие выражению с квантификатором будет считаться найден
ным. Например, оба выражения e{1,1}e{1,1} и e{2,2} соответствуют слову feel, но не соответствуют слову felt.
Записывать квантификатор после каждого выражения было бы слиш
ком утомительно, а сами регулярные выражения при этом было бы трудно читать. К счастью, язык регулярных выражений поддержива
ет несколько удобных сокращений. Если в квантификаторе указыва
ется только одно число, оно обозначает и минимум и максимум, то есть выражение e{2} – это то же самое, что выражение e{2,2}. И, как уже отмечалось в предыдущем разделе, если квантификатор не указан явно, предполагается, что он равен единице (например, {1,1}, или {1}),
то есть выражение ee – это то же самое, что выражение e{1,1}e{1,1}
или e{1}e{1}; оба выражения e{2} и ee соответствуют слову feel, но не соответствуют слову felt.
Бывает удобно использовать различные минимальное и максимальное значения. Например, чтобы найти совпадение со словами travelled и traveled (обе формы записи являются допустимыми) можно было бы
Символ
Значение
.
Соответствует любому символу, за исключением символа перевода строки, или любому символу,
если используется флаг re.DOTALL, или символу .
внутри символьного класса
\d
Соответствует цифре Юникода или [0 9], если используется флаг re.ASCII
\D
Соответствует нецифровому символу Юникода или [^0 9], если используется флаг re.ASCII
\s
Соответствует любому пробельному символу Юникода или
[ \t\n\r\f\v]
, если используется флаг re.ASCII
\S
Соответствует любому символу Юникода, не являющемуся про
бельным, или [^ \t\n\r\f\v], если используется флаг re.ASCII
\w
Соответствует символу «слова» Юникода или [a zA Z0 9_], если используется флаг re.ASCII
\W
Соответствует любому символу не«слова» Юникода или [^a zA
Z0 9_]
, если используется флаг re.ASCII
Флаги, стр. 533

528
Глава 12. Регулярные выражения использовать выражение travel{1,2}ed или travell{0,1}ed. Квантифи
катор {0,1} используется настолько часто, что для него появилось соб
ственное сокращение – ?; поэтому другой способ записи (к тому же ча
ще использующийся на практике) этого регулярного выражения вы
глядит так: travell?ed.
Имеются еще два сокращения для квантификаторов: + – обозначает
{1,n}
(«не менее одного»); * – обозначает {0,n} («любое число»). В обоих случаях n обозначает максимально допустимое для квантификатора число, которое обычно не менее 32 767. Все квантификаторы перечис
лены в табл. 12.2.
Таблица 12.2. Квантификаторы регулярных выражений
Квантификатор + очень удобен. Например, для поиска соответствий целым числам можно было бы использовать выражение \d+, так как оно совпадает с одной или более цифрами. Данное регулярное выра
жение может отыскать два совпадения в строке 4588.91, например,
Синтаксис
Значение
e?
или e{0,1}
Максимальный, соответствует нулевому или большему чис
лу вхождений выражения e
e??
или e{0,1}?
Минимальный, соответствует нулевому или большему чис
лу вхождений выражения e
e+
или e{1,}
Максимальный, соответствует одному или больше вхожде
нию выражения e
e+?
или e{1,}?
Минимальный, соответствует одному или больше вхожде
нию выражения e
e*
или e{0,}
Максимальный, соответствует нулевому или большему чис
лу вхождений выражения e
e*?
или e{0,}?
Минимальный, соответствует нулевому или большему чис
лу вхождений выражения e
e{m}
Соответствует точно m вхождениям выражения e
e{m,}
Максимальный, соответствует по меньшей мере m вхожде
ниям выражения e
e{m,}?
Минимальный, соответствует по меньшей мере m вхождени
ям выражения e
e{,n}
Максимальный, соответствует не более чем n вхождениям выражения e
e{,n}?
Минимальный, соответствует не более чем n вхождениям выражения e
e{m,n}
Максимальный, соответствует не менее чем m и не более чем
n
вхождениям выражения e
e{m,n}?
Минимальный, соответствует не менее чем m и не более чем n
вхождениям выражения e

Язык регулярных выражений в Python
529
4588.91
и 4588.91. Иногда длительное удержание клавиши приводит к появлению опечаток. Мы могли бы использовать выражение bevel+ed
для поиска допустимых форм написания beveled и bevelled, а также опечатки bevellled. Если бы потребовалось считать допустимой только форму записи с одним символом l и отыскать только формы записи с двумя или более символами l, мы могли бы применить регулярное выражение bevell+ed.
Квантификатор * используется реже – просто потому, что он может приводить к получению неожиданных результатов. Например, пред
положим, что требуется отыскать строки с комментариями в файлах с программным кодом на языке Python. Для этого мы могли бы попы
таться использовать регулярное выражение #*. Но такое выражение будет соответствовать любым строкам, даже пустым, потому что фраза
«совпадение с любым числом символов #» подразумевает и нулевое число совпадений. Если вы плохо знакомы с регулярными выраже
ниями, возьмите себе за правило вообще не использовать квантифика
тор *, а если вы используете его (или квантификатор ?), то обязательно убедитесь, что хотя бы одно подвыражение в регулярном выражении использует ненулевой квантификатор, то есть используется хотя бы один квантификатор, отличный от * и ?, так как оба они могут нахо
дить соответствие при нулевом числе совпадений.
Часто возможно заменить квантификатор * на квантификатор +, и на
оборот. Например, отыскать соответствие слову «tasselled», в котором присутствует хотя бы один символ l, можно с помощью выражения
tassell*ed
или tassel+ed, а соответствие формам записи с двумя или бо
лее символами l – с помощью tasselll*ed или tassell+ed.
Регулярное выражение \d+ будет соответствовать строке 136. Но поче
му оно соответствует всем цифрам, а не только первой? По умолчанию все квантификаторы являются жадными (или максимальными) – они стремятся соответствовать как можно большему числу символов. Лю
бой квантификатор можно сделать нежадным (или минимальным), до
бавив после него символ ?. (Знак вопроса имеет два разных значения –
когда он употребляется самостоятельно, он интерпретируется как со
кращенная форма записи квантификатора {0,1}, а когда следует за квантификатором – он говорит о том, что стоящий перед ним кванти
фикатор является минимальным.) Например, выражение \d+? обнару
жит соответствие в строке 136 в трех разных местах: 136, 136 и 136. Дру
гое выражение: \d?? соответствует нулевому или большему числу цифр, но предпочтение будет отдано нулевому числу совпадений, по
тому что используется минимальный квантификатор – он порождает ту же проблему, что и квантификатор *, и может находить соответст
вие «с ничем», то есть будет соответствовать вообще любому тексту.
Минимальные квантификаторы могут с успехом использоваться для быстрого и приблизительного синтаксического анализа документов в формате XML и HTML. Например, для поиска всех тегов изображе

530
Глава 12. Регулярные выражения ний можно было бы использовать выражение (соответствует одному символу «<», за которым следует символ «i», затем символ
«m», затем символ «g», затем ноль или более любых символов, за ис
ключением символа перевода строки, и затем символ «>»), но оно бу
дет давать неверные результаты, потому часть .* является жадной и будет соответствовать всему подряд, включая закрывающую угло
вую скобку тега «>», и остановится только по достижении последнего символа «>» в тексте.
Сами собой напрашиваются три варианта решения (кроме использова
ния нормального парсера). Одно из них – выражение ]*> (соот
ветствует подстроке волов, отличных от >, и затем следует закрывающая угловая скобка тега >), другое – выражение (соответствует подстроке >
, затем следует >) и третье решение является комбинацией двух пре
дыдущих – ]*?>. Но ни одно из них не является правильным,
потому что все они будут соответствовать строке , которая не яв
ляется допустимым тегом. Так как известно, что тег изображения дол
жен иметь атрибут src, можно записать более точное регулярное выра
жение ]*?src=\w+[^>]*?>. Это выражение соответствует всем литералам символов бельных символов, затем минимально ноль или более любых симво
лов, за исключением > (чтобы пропустить любые атрибуты, такие как alt
), затем атрибут src (символы src=, затем хотя бы один символ «сло
ва»), затем любой (включая нулевое число) символ, за исключением >,
чтобы пропустить любые другие атрибуты, и, наконец, закрывающая угловая скобка >.
Группировка и сохранение
На практике часто бывают необходимы регулярные выражения, соот
ветствующие любой из двух или более альтернатив, и нередко требует
ся сохранить совпадение или какуюто его часть для последующей об
работки. Кроме того, иногда требуется, чтобы квантификатор приме
нялся к нескольким выражениям. Все это может быть реализовано с помощью операции группировки (), а выбор альтернативных вари
антов можно реализовать с помощью конструкции выбора |.
Конструкция выбора особенно удобна, когда необходимо отыскать сов
падение с одной из нескольких альтернатив. Например, регулярное выражение aircraft|airplane|jet будет соответствовать любому тексту,
содержащему «aircraft», «airplane» или «jet». Тот же результат мож
но получить с помощью регулярного выражения air(craft|plane)|jet.
В данном случае круглые скобки используются для группировки вы
ражений, таким образом здесь имеются два внешних выражения:
1   ...   57   58   59   60   61   62   63   64   ...   74


написать администратору сайта