regulyarnyie-vyirazheniya-osnovyi (852744), страница 9
Текст из файла (страница 9)
(О том, где ее можно получить, см. в разделе "На заметку".) Чтобы проверить, как работает эта утилита,выполните следующую команду:pcregrep -с '\A\s*(THEIThelthe)' rime.txtкоторая вернет значение счетчика вхождений (-с) слова the (в трех вариантах написания), равное 108, при условии, что это слово встречается в начале строки и ему предшествуют нуль или более пробелов. Затем введите следующую команду:pcregrep -n • (МARINEREIMarinere) (.)?\Z' rime.txtГnава 3. Границы47Эта команда выполнит поиск слов MARINERE и Marinere, которые находятся в концестроки и за которыми может следовать необязательный произвольный символ, в данномслучае являющийся либо знаком препинания, либо буквой S.
(Скобки, окружающие точку, не играют никакой существенной роли.)В результате выполнения этой команды вы должны получить следующий вывод.9:37:63:105:282:702:It is an ancyent Marinere,The bright-eyed Marinere.The bright-eyed Marinere."God save thee, ancyent Marinere!"I fear thee, ancyent Marinere!Не loves to talk with MarineresОпция -n команды pcregrep задает вывод номеров строк. Опции утилиты pcregrepв своем большинстве аналогичны опциям утилиты grep. Их полный перечень можно получить с помощью такой команды:pcregrep --helpЗадание rруппы симвопов как питераповДля указания начала и конца группы символов, которые должны интерпретироватьсякак литералы, используются метасимволы\Qи\ЕЧтобы увидеть, как это работает, введите в нижнем текстовом поле RegExr следующиеметасимволы:.л$*+?1(){}[]\-В регулярных выражениях, используемых для кодирования шаблонов, все эти 15 метасимволов играют роль специальных символов.
(Дефис интерпретируется как специальный символ, если он используется для указания диапазона в квадратных скобках,определяющих символьный класс. Во всех остальных случаях он интерпретируется какобычный символ.)Если вы хотите найти совпадение с любым из этих символов, введя его в верхнем текстовом поле RegExr, то ничего не произойдет. Почему? Потому что RegExr думает (еслиприложение вообще способно думать), что вы вводите регулярное выражение, а не литеральные символы.
А теперь введите в верхнем текстовом поле следующий шаблон:\Q$\Eи вы увидите, что в нижнем текстовом поле выделится символ$, поскольку все, что заключено между \Q и \Е, интерпретируется как набор литеральных символов (рис. 3.3).(Вспомните, что обычно для того, чтобы превратить метасимвол в литерал, перед нимнадо ставить обратную косую черту.)48Глава 3.
ГраницыRegExrM.at.chReplaceSan1ptes\QS\E� globalНу SavedCommunity•J� show alJLJ ignor'll!Cas;eLJ e.xtended1а......оdotall.::!Jr,,ultil1ne\w. �s•+ ?1(){}[]\·\Wld\D\sIS{две}[�две}Mat:h&::; an� character exc-=pt for tinebreaks i� dotall ls falsta"Reg&p, /IQS\E/gmp_.�rn; \QS Еfl.tgs: 9mО c.11ph.lring groups:bOJ.Jt R4:9ExrCnlrneEcr!:10Рис. 3.3. Задание метасимвола как литералаДобавпение теrовСнимите в окне приложения RegExr флажок global и установите флажок multiline,щелкните на вкладке Replace (Заменить) и введите в первом текстовом поле (обозначенном цифрой 1 на рис.
3.4) следующее выражение:л (. *) $Это выражение найдет и запомнит первую строку текста. Затем введите в следующемполе (обозначенном цифрой 2) такой текст:<!DOCTYPE html>\n<html lang="en">\n<head><title>Rime</title>�</head>\n<body>\n<hl>$1</hl>После того как вы это проделаете, в поле результата (обозначенном цифрой 4) отобразится измененная версия исходного текста (обозначенного цифрой 3), которая теперьбудет включать добавленную вами разметку (рис. 3.4).Приложение RegExr позволило продемонстрировать, как добавить разметку в текст,но в остальном его возможности ограничены. Например, вы не сможете сохранить результат в файле, - для этих целей придется использовать другие инструменты.Гnава 3. Границы49RegE.xrMatchSamples.lL.J globalL-1 ignoreCase1.-..J e..ttended-J dotallMySavedComn11unityshow•II� multll1ne:html lang="en">\n<head><tltle>Rime</Ьtle></head>\n<body>\n<h 1 >S 1 </h 1 > 8\w\WТНЕ RIME OF ТНЕ АNСУЕ/П MAR!NERE, IN SEVEN PARTS.$\d\DARGUMENT.\sHow а Ship having pas5ed the Line VIЗS driven Ьу Storms to the coldCountry tow.1rds the South Pole: and how from thence she made her course15to the tropic:al Latitude of the Great Pacific OceвnJ and of the stгangethings that befell; and in what m.tnner tfie A.ncyent Mariner@ came back to< IООСТУРЕ html >(1<html lang="en•><head><title>Rime</title></head><body><hl>THE RIME OF ТНЕ ANCVENT MARINERE, Ifll SEVEN PARTS.</t,1>...Matche5 an.,, character, except for l1nebreaka 1f dotall 1s fats«ARGUMENТ,RegExp: tpattern: ""'(•)stm)5flags: m1 c.apturing groups:group 1: ( 8)J 1Ь bu1ft Ьg-:nner.comРис.
3.4. Добавление разметки с помощью RegExpДобавление теrов с помощью sedДля того чтобы получить аналогичный результат средствами командной строки, воспользуемся потоковым редактором sed, с которым вы уже познакомились в предыдущейглаве. Команда i (insert) редактора sed позволяет вставить текст перед определенной позицией в тексте. Другая команда - а (аррепd) - позволяет вставить текст после определенной позиции в тексте. Эту команду мы используем позже.Ниже приведена команда, которая вставляет определение типа документа HTMLSи некоторые другие теги, начиная со строки 1.sed '1 i\<!DOCTYPE html>\<html lang=\"en\">\<head>\<title>Rime</title>\</head>\<body>5/ Л /<hl>/s/$/<\/hl>/q' rime.txtСимволы обратной косой черты в конце строк обеспечивают возможность вставкиновых строк в поток и препятствуют преждевременному выполнению команды. Символы50Глава 3. Границыобратной косой черты перед кавычками экранируют их, чтобы они интерпретировалиськак литеральные символы, а не как часть команды.Вот как должен выглядеть вывод при правильном выполнении этой команды в sed.<!DOCTYPE html><html lang="en"><head><title>The Rime of the Ancyent Mariner (1798)</title></head><body><hl>THE RIМE OF ТНЕ ANCYENT МARINERE, IN SEVEN PARTS.</hl>Точно такие же команды sed хранятся в файле top.sed в архиве примеров.
Вы можетевыполнить их из файла с помощью следующей команды:sed -f top.sed rime.txtВы должны получить вывод, аналогичный предыдущему. Если это требуется, можноперенаправить вывод в файл:sed -f top.sed rime.txt > tempЭта команда не только отображает результат на экране, но и сохраняет вывод в файлеtemp за счет той части команды, которая отвечает за перенаправление вывода(> temp).Добавление теrов с помощью PerlПопытаемся сделать то же самое с помощью Perl. Для этого достаточно выполнитьследующую команду.perl -ne 'print "<!DOCTYPE html>\<html lang=\"en\">\<head><title>Rime</title></head>\<body>\.. if $.
== l;s/ л /<hl>/;s/$/<\/hl>/m;print;exit;' rime.txtСравните эту команду с аналогичной командой sed. Похожи ли они? Чем они отличаются? Команда sed выглядит немного проще, но, с моей точки зрения, команда Perl болеемощная.Проанализируем подробно, как это все работает.• Переменная $ . , значение которой проверяется в операторе if, представляет текущую строку. Возвратом значения true оператор if подтверждает, что текущаястрока является строкой 1.• Найдя строку 1 с помощью оператора if, Perl выводит директиву типа документаи несколько НТМL-тегов.
Как и в случае sed, кавычки необходимо экранировать.• Первая подстановка вставляет открывающий тег h 1 в начало строки, а вторая закрывающий тег hl в конец строки.• Символ m в конце второй подстановки означает, что используется модификаторmul tiline. Это делается для того, чтобы команда распознавала конец первойстроки. Если не использовать этот модификатор, символу $ будет соответствоватьконец файла.Глава 3.
Границы51• Команда print выводит результат выполнения подстановки.• Команда exit осуществляет немедленный выход из Perl. Без нее, в силу наличияопции -n, этот сценарий обрабатывал бы в цикле каждую строку, что в данномслучае нам не нужно.Поскольку ручной ввод этой команды довольно утомителен, я поместил в файл top.pl,который вы также найдете в архиве примеров, следующий код Perl.#!/usr/bin/perl -nif ($ == 1) {print "<!DOCTYPE html>\<html lang=\"en\">\<head>\<title>The Rime of the Ancyent Mariner (1798)</title>\</head>\<body>\";s/h/<hl>/;s/$/<\/hl>/m;print;exit;Этот код можно выполнить с помощью следующей команды:perl top.pl rime.txtПолученный вывод будет совпадать с предыдущим, хотя он и формируется немногоиначе. (Как и в случае sed, для перенаправления вывода можно использовать символ>.)О чем вы узнапи в rпаве 3• Как использовать якорные привязки в начале и в конце строки с помощью метасимволов \ л и $.• Как использовать границы слов и другие границы.• Как находить начало и конец подстроки с помощью метасимволов \А и \Z (или \z).• Как обозначать строки символов как литералы с помощью метасимволов \Q и \Е.• Как добавить НТМL-теrи в документ с помощью RegExr, sed и Perl.На заметку• Редактор vi (сокращение от visual) - редактор текстов со встроенным механизмом регулярных выражений, разработанный сотрудником компании Sun БилломДжоем в 1976 году.
Редактор vim (сокращение от vi improved) - усовершенствованный текстовый редактор, первоначально разработанный Брамом Моленаромна основе редактора vi (http://www. vim. org). Раннюю статью Билла Джояи Марка Хортона, содержащую описание редактора vi, можно прочитать здесь:ht tp: / /docs. freebsd. org/ 4 4doc/usd/ 12. vi /paper. html. Впервые52Глава 3. Границыя использовал его в 1983 году и с тех пор не расстаюсь с ним практически нина один день. В отношении выполнения больших объемов работы за короткоевремя редактору vi нет равных.
А кроме того, его возможности настолько широки,что я не перестаю удивляться тому, как много нового для себя я постоянно открываю несмотря на то, что мое знакомство с ним длится уже более тридцати лет.• Утилита grep - средство командной строки Unix, предназначенное для поиска и вывода строк с использованием регулярных выражений. Поговаривают, что на идею разработки этой утилиты, предложенной в 1973 году, ее создателя Кена Томпсона натолкнула одна из команд редактора ed: g/re/p (global/regular expression/print). Впоследствии она была вытеснена, хотя и не полностью, утилитой egrep (или grep -Е), использующей расширенные регулярные выражения (ERE) с такими дополнительными метасимволами, как 1 , +,?,( и ) .