Саммерфилд - Программирование на Python 3 (1077331), страница 120
Текст из файла (страница 120)
Проверки регулярных выражений Символ Значение о Флаги регулярных выражений, сгр. 535 Соответствует началу текста; кроме того, с фла гом ге. ИЧСТ1С[ИЕ соответствует позиции сразу по еле каждого символа перевода строки Соответствует концу текста; кроме того, с флагом ге. ИЧ(11(1МЕ соот- ветствует позиции перед каждым символом перевода строки ЧА Соответствует началу текста Соответствует границе в слова в; поведение проверки зависит от фла- га ге. АБС11 — внутри символьных классов обозначает символ забоя ()>ас)<ерасе) Соответствует границе не-всловав; поведение проверки зависит от флага ге. АВС11 Чз Соответствует концу текста Совпадение обнаруживается, если текст справа от позиции провер- ки соответствует выражению е, при этом изменение позиции поиска в тексте не происходит — эта проверка называется опережающей про- веркой, или позитивной опережающей проверкой (2=е) Совпадение обнаруживается, если текст справа от позиции провер- ки не соответствует выражению е, прн этом изменение позиции по- иска в тексте не происходит — эта проверка называется негативной опережающей проверкой (2!е) Совпадение обнаруживается, если текст слева от позиции проверки соответствует выражению е, эта проверка называется позитивной ретроспективной проверкой (2<=е) (2<(е) Совпадение обнаруживается, если текст слева от позиции проверки не соответствует выражению е, зта проверка называется негатив- ной ретроспективной проверкой выражения.
Лучшее решение заключается в использовании флага ге, ЧЕЯВОВŠ— он позволяет использовать внутри регулярных выражений пробельные символы и обычные комментарии языка Ру1)топ с одним ограничением — когда необходимо описать совпадение с пробельным символом, следует испольэовать либо символ хв, либо символьный класс, такой как [ 3. Ниже приводится регулярное выражение, отыскивающее пары ключ=значение, с комментариями: 535 язык регулярных выражений в ру1)гоп Таблица 12.4. Флаги модуля регулярных выражений Значение Флаг При наличии этого флага проверки ~Ь, ~В, ~з, ~8, ~к и зв действуют так, как если бы оии применялись к тексту, содержащему только символы АЗСП; по умолчанию действие этих проверок основано иа спецификации Юяикодз ге.
А или ге. АОС11 Поиск совпадений выполняется без учета рагистрз символов ге. 1 или ге. 1ОИОНЕСАОЕ При наличии этого флага символ соответствует началу текста и позиции сразу же после каждого символа перевода строки, в символ 8 соответствует позиции перед каждым символом перевода строки и концу текста ге. И или ге. ИОСТ1СТИЕ При наличии этого флага символ . соответствует лю- бому символу, включая сямэол перевода строки ге. 8 ияи ге. ООТАСС Позволяет включать е регулярные выражения пробе- лы и комментарии ге. Х или ге.
НЕНВОВЕ В контексте программирования на языке Ру1Ьоп регулярные выражения, подобные этому, обычно записываются в виде «сырых» строк, заключенных в тройные кавычки, — «сырые» строки используются, чтобы избежать необходимости дублировать символы обратного слеша, а тройные кавычки — чтобы регулярное выражение можно было записывать в нескольких строках. В дополнение к проверкам, обсуждавшимся до сих пор, существуют дополнительные проверки, которые заглядывают по тексту вперед (или назад) от точки проверки„чтобы узнать, соответствует ли (или не соответствует) определенное нами выражение.
Выражения, которые могут использоваться в ретроспективных проверках, должны иметь фиксированную длину (то есть в них не могут использоваться квантификаторы 7, + и *, а интервальные квантификаторы должны задавать фиксированный размер, например, (3)). В случае регулярного выражения, отыскивающего совпадения со строками в формате ключ=значение, негативная обратная проверка для совпадения требует, чтобы символы, нредшесазвующие позиции проверки, не были пробелами или символами табуляции. Вследствие этого последний символ «значения» сохраняется в сохраняющей группе, а завершающие пробелы и символы табуляции — нет (это не относится к пробелам и символам табуляции внутри сохраненного текста). Рассмотрим другой пример.
Предположим, что мы читаем многострочный текст, содержащий имена «Не1еп Ра(г1с1а В)загшап», «гйш ВЬагшап», «В)загшап дов)з1», «Не1еп Ке11у» и т. д., и нам необходимо отыскать текст «Не1еп РаСг1с1а», но только если он относится к имени 536 Глава 12. Регулярные выражения «Не1еп Ра1г(с1а ЯЬагтап». Простейший способ заключаетея в том, чтобы использовать регулярное выражение 1Ь(Нв1вп1з+Рвтг1с1в)1з+ЗЬвгввп'1Ь. Однако того же самого можно добиться с помощью опережающей проверки, например, ~Ь(Не1еп1з+Рзтг1с1в)(?=~з+Зпвгвап1Ь). Этому выражению будет соответствовать текст «Не1еп Разг(с1а», только если он предшествует границе слова, за которым следуют пробельные символы и слово «ЯЬагшап» и далее следует граница слова. Чтобы сохранить определенное имя в самых разных его разновидностях («Не1еп», «Не1еп Р.» или «Не1еп Ра(г1с1а»), можно было бы создать немного более сложное регулярное выражение, например, 1ь(не1вп(?:1з+(?:Р1.
1Ратг1с1в))?)1з+(?=Зпвгввп1Ь). Ему соответствует граница слова, за которой следует имя в одной из форм, но только если вслед за ним следует некоторое число пробельных символов, затем слово «Не1еп Ра(г(с(а Яйагшап» и граница слова. Обратите внимание, что сохранение выполняется только двумя синтаксическими конструкциями — (е) и (?Р<пазе>е). Других форм сохраняющих группировок в круглых скобках не существует. Это особенно важно для опережающих и ретроспективных проверок, так как они лишь проверяют последующий или предшествующий текст — сами они не являются частью совпадения, а только проверяют факт наличия или отсутствия совпадения.
Это также важно для последних двух синтаксических конструкций в круглых скобках, которые мы теперь рассмотрим. Ранее мы уже видели, что получить доступ к сохраненному тексту внутри регулярного выражения можно либо по номеру группы (например, ~1), либо по имени (например, (? Р=паее)). Однако имеется возможность принимать решение о наличии соответствия в зависимости от наличия предыдущего совпадения. Для етого используются синтаксические конструкции (?(!г!)уез ехр) и (?(!б)уез ехр~ло ехр).
Эдесыг!— зто имя или номер предыдущей сохраняющей группы. Если для указанной группы совпадение было обнаружено, здесь будет выполняться проверка на совпадение с выражением уез ехр. Если для указанной группы совпадение не было обнаружено, то здесь будет выполняться проверка на совпадение с выражением по ехр, если оно определено. Рассмотрим пример. Предположим, что необходимо извлечь имена файлов, которые упоминаются в атрибутах з ге тегов 1вс в документе НТМ1 . Для начала попробуем просто отыскать атрибут згс, но, в отличие от предыдущих попыток, мы учтем тот факт, что значение атрибута может указываться в трех формах: в апострофах, в кавычках и без кавычек.
Вот первая попытка: згс=(("'])((""'>]+)11. Часть ([""'>]+) сохраняет найденное совпадение максимальной длины, содержащее по меньшей мере один символ, который не является кавычкой, апострофом или >. Это регулярное выражение прекрасно работает, когда имена файлов указываются в кавычках, а благодаря обратной ссылке ~1 соответствие будет обнаружено, только если кавычки, обрамляющие 537 Язык регулярных выражений е Ру1Иол <зиоНз+ Г>] 7 в го= (2Р<дио1е>["'])2 (2Р<аиаее>[""'>]+) (7(сиота)(2Р=Оооте)) [">]*7 > а начало тега в любые атрибуты, лредшвствующие згс в начало атрибута згс в необязательная откриввющая кавычка а иия Файла изображения в закрывающая кавычка (если была открывающая кавычка) в любыв атрибути, следующие за вгс а конец тога Сохраняющей группе с именем файла было присвоено имя "зщзде" (этой группе соответствует порядковый номер 2).
Конечно, существует более простая, но менее очевидная альтернатива: агси(["']7)([""'>]ь)11. Здесь, если имеется символ открывающей кавычки, он сохраняется в группе 1, далее идут символы, следующие за открывающей кавычкой. Если в определении атрибута открывающая кавычка отсутствовала, по-прежнему будет считаться, что для группы 1 было найдено совпадение — совпадение с пустой строкой, так как кавычка считается необязательной (ее квантификатор означает ноль или более совпадений); в этом случае обратной ссылке также будет соответствовать пустая строка. Наконец, механизм регулярных выражений в языке Рус]>оп предоставляет возможность устанавливать флаги, влияющие на работу регулярных выражений.
Обычно флаги устанавливаются посредством их передачи функции ге. ссщр>1е() в виде дополнительных параметров, но иногда гораздо удобнее устанавливать их непосредственно в регулярных выражениях. Установка флагов выполняется простой синтаксической конструкцией (7Р1адэ), где Р]адэ — один или несколько следующих флагов: а (то же самое, что передача флага ге. АВС11), з (ге. 16ИОЯЕСАЬЕ), щ (ге. ИОСТ][]ИЕ), з (ге. ОСТА[[) и х (ге. НЕЯВОВЕ).' При таком В языке Руз)гоп используются те же символы флагов, что и в механизме ре- гулярных выражений языка Рег!, поэтому символ з обозначает флаг ге. 00- ТАьь, а символ х — флаг ге. НЕЯВОВЕ. имя файла, — одного типа.
Но это выражение не позволяет отыскивать имена файлов без кавычек. Чтобы устранить эту проблему, необходимо сделать символ открывающей кавычки необязательным, а совпадение с закрывающей кавычкой выполнять, только если было найдено совпадение с открывающей кавычкой.