regulyarnyie-vyirazheniya-osnovyi (852744), страница 15
Текст из файла (страница 15)
Этоплатный продукт, но вы можете бесплатно протестировать его и, если он вам понравится, приобрести по умеренной цене (существуют две версии продукта: стандартная и профессиональная).• Редактор vim (http://www.vim.org) - усовершенствованная версия редактора vi, написанного Биллом Джоем.
Основным разработчиком редактора vim былБрам Молинар. Непосвященным редактор vim покажется архаичным, но, какя уже отмечал, он обладает невероятно мощными возможностями.• Утилита ack (http://betterthangrep.com) написана на языке Perl. Она работает приблизительно так же, как и утилита grep, и имеет ряд собственныхопций командной строки, но превосходит grep во многих отношениях. Например, в ней используются регулярные выражения Perl, а не базовые регулярныеГnава б.
Сопоставnение с симвоnами Unicode и другими симвоnами85выражения grep (без опции -Е). Инструкции по ее установке вы найдете по адресуhttp: //betterthangrep.com/install//. Я следовал инструкциям, описанным в разделе "Install the ack executaЫe': но при этом не использовал утилиту curl,а просто загрузил ack, воспользовавшись предоставленной там ссылкой, и скопировал сценарий в каталог !usr!Ьin как на своем компьютере Мае, так и на компьютере, работающем под управлением Windows 7 с установленной программойCygwin (http://www.cygwin. сот).86Глава 6.
Сопоставление с символами Unicode и другими символамиГЛАВА 7КвантификаторыНекоторые квантификаторы уже встречались вам в приведенных ранее примерах,а теперь мы обсудим их более подробно.На этот раз, как и в главе 5, мы будем выполнять примеры с помощью настольногоприложения Reggy (рис. 7.1) для компьютеров Мае. Перед началом работы снимите флажок Match AII в нижней части окна.Если в вашем распоряжении нет компьютера Мае, воспользуйтесь любым другимприложением из числа тех, которые мы до этого обсуждали.
Скопируйте в приложениесодержимое файла triangle.txt, в котором цифры расположены в строках таким образом,чтобы образовался прямоугольный треугольник. Этот файл включен в архив примеров.Reggy(Н) 0\d\1223334444555556666667777777888888889999999990000000000O M8'dl AII O M,rd> С..•�М\1111 ntРис. 7.1. Приложение ReggyIМ.,tc11FoundЖадный, nенивый и сверхжадный поискНесмотря на то что прилаrательные, стоящие в заrоловке, отражают не самые лучшиечеловеческие качества, они представляют интересные свойства квантификаторов, которые вы обязательно должны понимать, если хотите работать с реrулярными выражениями на профессиональном уровне.Обычный квантификатор изначально является "жадным" (greedy).
Жадный квантификатор в первую очередь стремится обнаружить совпадение со всей строкой. Он захватывает столько, сколько может, целую строку, пытаясь обнаружить совпадение. Еслипервая попытка оказывается неудачной, он возвращается на один символ и повторяетпопытку. Этот процесс называют бектрекингом или поиском с возвратом. Пошаrовыйвозврат на один символ продолжается до тех пор, пока не будет обнаружено совпадениеили не исчерпаются все символы. Кроме тоrо, жадный квантификатор сохраняет информацию о каждом своем действии и поэтому потребляет наибольшее количество ресурсовпо сравнению с двумя друrими разновидностями квантификаторов, к рассмотрению которых мы переходим.Ленивый {lazy) квантификатор (друrое название - нежадный) действует иначе.
Онпытается обнаружить совпадение, начиная с самоrо первоrо символа тестируемой строки. Далее он просматривает всю строку по одному символу за раз в поиске совпадения.Наконец, он пытается найти совпадение со всей строкой. Чтобы превратить обычныйквантификатор в ленивый, перед ним необходимо записать вопросительный знак(?). Ленивый квантификатор "пережевывает" строку небольшими порциями.Сверхжадный (possessive) квантификатор пытается найти совпадение, захватывая целиком всю строку, но делает это в рамках одной попытки, не прибеrая к поиску с возвратом.
Чтобы превратить обычный квантификатор в сверхжадный, перед ним необходимозаписать знак "плюс"( + ). Сверхжадный квантификатор не тратит время на "пережевывание" строки, а "rлотает" ее целиком и только после этоrо пытается понять, а что жеименно он "съел". Перейдем к более подробному рассмотрению каждоrо из вышеперечисленных типов квантификаторов по отдельности.Сопоставnение с испоnьзованиемквантификаторов *, + и ?Вы уже перенесли в Reggy треуrольник из цифр? Тоrда мы можем приступить к тестированию. Прежде всеrо, используем звезду Клини - символ "звездочка"(*), названныйтак в честь Стивена Клини, разработавшеrо формальную теорию реrулярных выражений.
Если записать звездочку вслед за точкой:*то это выражение, будучи жадным, совпадет со всеми символами (в данном случае цифрами) тестируемого текста. Как вам уже известно из предыдущих rлав, последовательности . * соответствует любой одиночный символ, повторяющийся нуль или болеераз. Таким образом, в результате применения этоrо выражения к тексту в нижней области окна выделенным окажется весь текст. В одном из ранних руководств по реrулярнымвыражениям о звезде Клини сказано следующее:88Глава 7. КвантификаторыРегулярному выражению, за которым следует символ "•" [звезда Клини], соответствует любое количество (включая нулевое) следующих подряд вхождений текста,соответствующего данному регулярному выражению.Если вы попробуете применить выражение9то увидите, что выделится весь нижний ряд девяток. Однако в результате применениявыражения9.*выделится не только ряд девяток, но и ряд нулей под ним. Почему это произошло? Потому что флажок Multiline (в нижней части окна приложения) установлен, и поэтому символы новой строки также будут соответствовать точке, чего не будет происходить приснятом флажке.Для поиска совпадений с одной или несколькими девятками введите такое выражение:9+Чем это выражение отличается от предыдущего? Основное отличие состоит в том,что квантификатор + ищет по крайней мере одно вхождение цифры 9, тогда как квантификатор * ищет нуль или более вхождений.Следующему выражению соответствует нуль или одно (необязательное) вхождениецифры 9:9?Этому выражению соответствует лишь первое вхождение цифры 9.
Она указана какнеобязательная во второй позиции, но поскольку она уже существует в проверяемомтексте в первой позиции, она включается в соответствие и выделяется цветом. Если выиспользуете следующее выражение:99?то выделится как первая, так и вторая цифра 9.В табл. 7.1 приведены базовые квантификаторы вместе с описанием их функций. Всеэти квантификаторы по умолчанию жадные, т.е.
они пытаются найти совпадение с максимально возможным количеством символов с первой попытки.Таблица 7. 1. Базовые квантификаторыСинтаксисОписание?Предыдущий символ или группа символов может встретиться в данной позиции нуль ИЛИ ОДИН раз+Предыдущий символ или группа символов может встретиться в данной позиции один или более раз*Предыдущий символ или группа символов может встретиться в данной позиции нуль или более разГnава 7.
Квантификаторы89Соответствие заданному копичеству повторений симвопаФигурные скобки позволяют создавать шаблоны, которым соответствует определенное количество повторений символа, попадающее в указанный диапазон значений. Еслиповедение этих квантификаторов не изменено с помощью модификаторов, они ведутсебя как жадные. Например, выражению7{1}будет соответствовать первое вхождение цифры 7. Если вы хотите, чтобы этому выражению соответствовало одно или более вхождение цифры 7, в него необходимо добавитьзапятую:7 { 1,}Вероятно, вы уже догадались, что выражения7+и7 { 1,}фактически означают одно и то же.
Точно так же одинаковый смысл имеют выраженияи7*7 {О,}То же самое остается справедливым и в отношении пары выраженийи7?7 { О, 1}Для указания некоторого диапазона допустимого количества повторений, когда цифра, символ или группа может встречаться не менее т раз, но не более т раз, используйтевыражения следующего типа:7{3,5}Данному выражению будут соответствовать три, четыре или пять следующих подрядцифр 7.Как вы имели возможность убедиться, синтаксис, предполагающий использованиедиапазонов, задаваемых с помощью фигурных скобок, является наиболее гибким. Сводкаэлементов этого синтаксиса приведена в табл.
7.2.Таблица 7 .2. Синтаксис фигурных скобокСинтаксисОписание{n}Соответствует ровно n следующим подряд вхождениям предыдущего символа или группы{n,}Соответствует n или более следующим подряд вхождениям предыдущегосимвола или группы90Гnава 7. КвантификаторыОкончание табл. 7.2СинтаксисОписание{m,n}Соответствует не менее чем n и не более чем m следующим подряд вхождениям предыдущего символа или группы{ о, 1}То же самое, что и ? (отсутствие или однократное вхождение предыдущегосимвола или группы){ 1, О}То же самое, что и+ (одно или более следующих подряд вхождений предыдущего символа или группы){О,}То же самое, что и \ * (отсутствие или любое количество следующих подрядвхождений предыдущего символа или группы)Ленивые квантификаторыДавайте избавимся от жадности и предадимся лени. Вам будет гораздо легче во всемразобраться, если мы обратимся к конкретным примерам. Прежде всего убедитесь в том,что в приложении Reggy установлен флажок Match AII, и попытайтесь найти совпадениес нулевым или единичным количеством повторений цифры 5, используя одиночный вопросительный знак(?):5?Выделится первая цифра 5.
Добавьте дополнительный знак ?, чтобы сделать квантификатор ленивым:5??В этом случае ни один символ не выделяется. Причина заключается в том, что данныйшаблон - ленивый, и ничто не вынуждает его выделить первую цифру 5. По самой своейсути ленивые выражения стремятся совпасть с как можно меньшим допустимым количеством символов. На то они и лентяи!Если вы попытаетесь использовать следующее выражение:5*?то убедитесь в том, что ни одна из цифр не будет выделена, поскольку символ ? позволяет шаблону считать соответствие найденным, даже если цифра 5 в него не включена,что и произошло.Проверьте, к чему приведет следующее выражение:5+?Увидели? Ленивец оторвался от дивана и нашел одну цифру 5.
Это было все, чтоот него требовалось, чтобы выполнить рабочую норму.Разнообразим пример, используя диапазонный поиск т,п:5{2,5)?Это выражение совпадет всего лишь с двумя цифрами 5, чего и следовало ожидатьот ленивого поиска.Глава 7. Квантификаторы91Полный перечень ленивых квантификаторов приведен в табл. 7.3. В каких случаяхполезны ленивые выражения? Используйте их тогда, когда требуется найти минимальнодопустимое количество повторений символа, а не максимально возможное.Таблица 7 .З.