regulyarnyie-vyirazheniya-osnovyi (852744), страница 11
Текст из файла (страница 11)
(Поиск совпаденийначинается с крайнего слева шаблона.)А вот пример, в котором работа одного подшаблона (подшаблонов) зависит от результатов работы предыдущего:(tlT)h(eirle)Этому выражению будут соответствовать подстроки, начинающиеся с одной из буквt или Т, за которой следует буква h, за которой, в свою очередь, следует либо последовательность букв eir, либо буква е. Таким образом, данный шаблон совпадет с любым изследующих слов:•the•The•their•TheirВ данном случае второй подшаблон - ( е I е i r) - зависит от первого - ( t I Т) .Использовать круглые скобки в подшаблонах необязательно. Вот пример определенияподшаблонов с помощью классов:\b[tT]h[ceinry]*\bКроме слов the и The данному шаблону будут соответствовать также слова thee, thy,thence и много других.
Указание двух границ слов (\Ь) означает, что шаблону будут соответствовать только целые слова, а не подстроки, входящие в состав других слов.Глава 4. Альтернативы, группы и обратные ссылки59Проанализируем, как работает этот шаблон.• Метасимволу \Ь соответствует начало слова.• Выражение [ t Т] - это символьный класс, которому соответствует либо буква tнижнего регистра, либо буква Т верхнего регистра.• Далее шаблон находит (или пытается найти) букву h нижнего регистра.• Второй (и последний) подшаблон также записан в виде символьного класса[ceinry] с последующим квантификатором, которому соответствует нуль илинесколько символов.• Наконец, шаблон оканчивается еще одной границей слова \Ь.Хочу обратить ваше внимание на одну интересную особенность, характеризующую нынешнее состояние дел в области регулярных выражений.
Будучи, какправило, строгой, терминология регулярных выражений в некоторых случаяхдовольно размыта. Пытаясь дать определения подшаблона и некоторых другихтерминов, используемых в данной книге, я просмотрел множество источников, стремясь привести их к общему знаменателю. Подозреваю, кое-кто можетутверждать, что символьный класс нельзя причислять к подшаблонам. Но, поскольку символьные классы могут функционировать как шаблоны, я считаю,что для применения к ним термина "подшаблон" есть все основания.Захватывающие rруппы и обратные ссыnкиЕсли весь шаблон или некоторая часть его содержимого заключается в круглые скобки, образуя группу, то содержимое этой группы захватывается и временно сохраняетсяв памяти.
Впоследствии на сохраненное содержимое можно ссылаться с помощью обратных ссылок вида\1или$1где переменные \ 1 или $1 ссылаются на первую захваченную группу, \ 2 или $ 2 на вторую и т.д. Редактор sed воспринимает лишь ссылки вида \1, тогда как Perl воспринимает ссылки обоих типов.Первоначально в редакторе sed разрешалось использовать только ссылки в диапазоне от \ 1 до \ 9, но в настоящее время это ограничение, по всей видимости,снято.С подобным вы уже встречались в предыдущих главах, однако я все же приведу соответствующий пример.
Его суть заключается в перестановке слов в одной из строк поэмы,за что я заранее приношу свои извинения ее автору Сэмюэлу Тейлору Кольриджу. Щелкнув в окне приложения RegExr на вкладке Replace, введите в верхнем текстовом полеследующий шаблон:(It is)60(an ancyent Marinere)Глава 4. Альтернативы, группы и обратные ссыпкиПрокрутите обрабатываемый текст (верхняя текстовая область) вниз, пока не увидитеподсвеченную строку, и введите во втором текстовом поле следующий текст:$2 $1В результате в этой строке слова окажутся переставленными (рис. 4.2):an ancyent Marinere It is,R•9ExrМ.tchSan,ples{It ls) (•n ancyent Marln@re)L.J globalLJ lgnoreCa1etL-.J extendedL., dota/1MyS.vNCommunityshow allLI multiline\wS2 51IW!.\dIt is an •ncyent M•rlnere,And he stoppeth on• of thr@e:"Bv thy long grey be•rd and Н,у glittering е\•е"Now vA-тerefore stoppest me"'i'h• Bridegroom's doors are open'd WdeD\s\S[дВС][ЛдВС]!.an ancyent Mo1rinere It is,And ha atoppeth one of three:''Ву thy long grey beard o1nd thy gtittering еуе"Nov1 wherefore stoppest me"Matches any cha�cter that 1s not а d1g1tcharacter (0·9)."Th• Brldegroom's doors are open'd wideRegExp: /(It ••) (an ancyent Marlnere)/piltt@rn: (It is) (an o1ncyent Marinere)ftags:2 upturing 9roups:group 11 It 1sgюup 2J (an ancyent Mennere)3 �Ь burlt Ьу 'fSku,n r,«:ornРис.
4.2. Испот,зование обратн111х ссылок $1 и $2Для получения того же результата с помощью редактора sed необходимо выполнитьследующую команду:sed -En 's/(It is) (an ancyent Marinere)/\2 \1/р' rime.txtПолучаемый при этом выводan ancyent Marinere It is,полностью согласуется с результатом, полученным с помощью приложения RegExr. Нижеприведен подробный анализ работы данной команды.• Опция -Е означает, что вы хотите использовать расширенные регулярные выражения (ERE), что, в частности, позволяет избавиться от экранирования скобок.• Опция -n подавляет заданный по умолчанию вывод каждой строки.• Команда подстановки выполняет поиск совпадения с текстом "lt is an ancyentMarinere': захватывая его в две группы.Глава 4.
Альтернативы, группы и обратные ссылки61• Та же команда подстановки направляет в вывод измененную строку, полученнуюпутем перестановки местами частей исходной строки, доступных по обратнымссылкам \1 и \2.• Символ р в конце команды подстановки означает вывод строки на печать.Аналогичная команда Perl выглядит следующим образом:perl -ne 'print if s/(It is) (an ancyent Marinere)/\2 \1/'�rime.txtЗаметьте, что в этой команде используется синтаксис обратных ссылок в стиле \ 1.Разумеется, в Perl с равным правом можно использовать синтаксис вида $1:perl -ne 'print if s/(It is) (an ancyent Marinere)/$2 $1/'�rime.txtМне нравится та простота, с какой Perl позволяет вывести выделенную строку на печать.Скажу несколько слов о полученном выводе:an ancyent Marinere It is,Преобразование нарушило общепринятые правила использования прописныхи строчных букв, но Perl позволяет исправить это с помощью директив \u и \1:perl -ne 'print if s/ (It is) (an ancyent Marinere)/\u$2�\1$1/' rime.txtТеперь результат выглядит гораздо лучше:An ancyent Marinere it is,Объясню, как мы этого добились:• символ \ u ничему не соответствует и преобразует следующий символ в верхнийрегистр;• символ \1 ничему не соответствует и преобразует следующий символ в нижнийрегистр;• директива \U (здесь не используется) преобразует все символы следующей строкив верхний регистр;• директива \L (здесь не используется) преобразует все символы следующей строкив нижний регистр.Эти директивы действуют до тех пор, пока не будут отменены (например, \1 отменяет действие \U).
Поэкспериментируйте с ними самостоятельно, чтобы проверить, какони работают.Именованные rруппыИменованнь1е группы - это захватывающие группы, которым присвоены имена. Доступ к сохраненному содержимому таких групп может осуществляться с использованиемимен, а не целых чисел. Их использование демонстрируется ниже на примере Perl.perl -ne 'print if s/(?<one>It is) (?<two>an ancyent Marinere)/�\u$+{two}\l$+{one}/' rime.txt62Гnава 4.
Аnьтернативы, группы и обратные ссыnкиВ этой команде именованные группы создаются и используются следующим образом.• Присвоение группам имен one и two осуществляется путем дописывания последовательностей ?<one> и ?<two> в начале содержимого соответствующей группы в круглых скобках.• Последовательность $+ {one} ссылается на группу one, а последовательность$+ {two} - на группу two.Допускается повторное использование именованных групп в том шаблоне, в которомони были поименованы. Сейчас поясню, что имеется в виду. Предположим, выполняетсяпоиск строки, содержащей подстроку в виде шести следующих подряд нулей:000000Это тривиальный пример, но для наших целей его будет вполне достаточно. Присвоим имя группе, состоящей из трех нулей, с помощью следующего шаблона (имя z выбрано произвольно):(?<z>О{З})Далее эту группу можно использовать примерно так:(?<z>O{З})\k<z>так:(?<z>O{З})\k'z'или так:(?<z>O{З})\g{z}Апробируйте эти выражения в RegExr, и вы убедитесь в том, что все они отличноработают.
Ряд других синтаксических конструкций, предназначенных для работы с именованными группами, приведен в табл. 4.3.Таблица 4.3. Синтаксис именованных группСинтаксисОписание(?<имя> ...)Именованная группа(?имя...)Другая именованная группа(?Р<имя> ...)Именованная группа в Python\k<имя>Ссылка на группу по ее имени в Perl\k'имя'Ссылка на группу по ее имени в Perl\g{имя}Ссылка на группу по ее имени в Perl\k{имя}Ссылка на группу по ее имени в .NET(?Р=имя)Ссылка на группу по ее имени в PythonГnава 4. Аnьтернативы, группы и обратные ссыnки63Незахватыващие rруппыСуществуют также незахватывающие группы, содержимое которых не сохраняетсяв памяти.
Иногда это оказывается преимуществом, особенно в тех случаях, когда вы несобираетесь ссылаться на группу. Отсутствие необходимости сохранения данных в памяти может обеспечивать более высокую производительность, хотя при выполнении простых примеров, приведенных в данной книге, об этом вряд ли стоит задумываться.Помните, что собой представляла первая из групп, которые обсуждались в этой главе? Вот как она выглядела:(thelThelTHE)Никакой необходимости в использовании обратных ссылок здесь нет, поэтому можносоздать незахватывающую группу такого вида:(?:thelThelTHE)По аналогии с примером, приведенным в самом начале главы, в это выражение можно было бы добавить опцию, делающую шаблон нечувствительным к регистру (хотя этаопция фактически устраняет необходимость в использовании группы):(?i) (?:the)Эту же группу можно записать в таком виде:(?: (?i)the)а еще лучше в таком:(?i:the)Букву i, устанавливающую данную опцию, можно записывать между вопросительным знаком и двоеточием, что и было сделано в последнем случае.Атомарные rруппыАтомарные групт,1 - это разновидность незахватывающих групп.
В случае использования движка регулярных выражений, работающего в режиме поиска с возвратом, атомарная группа отключает этот режим, но не для всего регулярного выражения, а лишьдля той его части, которая заключена в данной группе. Соответствующий синтаксис выглядит примерно так:(?>the)В каких ситуациях имеет смысл использовать атомарные группы? К числу операций,способных существенно замедлять работу механизма регулярных выражений, относится поиск с возвратом. Это связано с тем, что такой поиск требует перебора всех возможностей, на что уходит много времени и расходуются значительные вычислительныересурсы. Иногда операции такого рода становятся основными пожирателями времени.Существует даже термин - катастрофический поиск с возвратом.Можете либо вообще отказаться от поиска с возвратом, используя движки наподобиеre2 (http: //code.