Когда некоторые говорят, что программы на
m/<A[^>]+?HREF\s*=\s*["']?([^'" >]+?)['"]?\s*>/ig
(Это всего-навсего шаблон для поиска гиперссылок в
Начнем с того, что
Основная идея
Наверное, чаще всего =~ к строке:
'В строке образец есть' =~ /образец/; # образец найден
Обычно поиск образца выполняется с учетом регистра, но можно игнорировать регистр при сопоставлении строки с образцом, если в операции сопоставления задать модификатор /i (
use locale; 'В строке образец есть' =~ /Образец/; # образец НЕ найден! 'В строке образец есть' =~ /Образец/i; # образец найден
Результат операции сопоставления в тексте можно присвоить скалярной переменной или использовать в любой из условных конструкций, например:
$text = 'Черный кот в темной комнате'; # ищем в этом тексте $found = $text =~ /кот/; # в $found будет '1' print 'Кошки нет!' unless $text =~ /кошка/; # вернет ''
Последнее предложение можно переписать, применив операцию отрицательной привязки к строке ( !~ ), которая инвертирует (меняет на обратный) результат операции сопоставления:
print 'Кошки нет!' if $text !~ /кошка/;# вернет '1'
Если операция привязки к строке не используется, образец отыскивается в переменной по умолчанию $_. Выражение перед поиском интерполируется, поэтому весь образец поиска или его часть может содержаться в переменной. Например:
$_ = 'Счастье - это когда тебя понимают.'; # переменная поиска $pattern = 'Счастье'; # образец для сопоставления print "$pattern найдено!" if /$pattern/;
В составе образца поиска могут применяться не только переменные, но и
print 'В строке обнаружена табуляция' if $string =~ m{\t};
Для успешного сопоставления строки образцу достаточно найти в строке первое совпадение. В этом примере образец совпадет с началом подстроки 'которого':
$text = 'У которого из котов зеленые глаза?'; # ищем здесь $any = $text =~ /кот/; # образец совпал с 'которого'
Чтобы найти именно
$cat = $text =~ / кот/; # образец совпадет с ' кот'
В операции сопоставления программист может задавать ограничители для образца: в этом случае перед ограничителями указывается буква m// (Операцию сопоставления часто именно так и называют: операция m//.) В качестве ограничителей могут выступать различного вида скобки или парные небуквенные символы, например:
m($pattern) m{$pattern} m[$pattern] m<$pattern>
m|$pattern| m!$pattern! m"$pattern" m#$pattern#
Задать собственные ограничители бывает особенно
/\/usr\/bin\/perl/
m{/usr/bin/perl}
Недаром обилие левых и правых наклонных черт в первом варианте называют "ученическим синдромом зубочисток" (LTS - index(). Самое интересное начинается тогда, когда в образце поиска применяются
Очень часто требуется искать в тексте не конкретные строки, а символьные последовательности, определенные приблизительно: "число в скобках", "четвертое слово с начала строки", "
{} [] () ^ $ . | * + ? \
При необходимости включить в образец поиска один из этих знаков не как метасимвол, а как обыкновенный символ, нужно отменить его особое значение ("экранировать"), поставив перед ним обратную косую черту (
$text =~ m"\." # содержится ли в тексте точка?
Как метасимвол точка обозначает в регулярном выражении один любой символ, кроме знака перевода новой строки (\n). Например, для поиска похожих слов можно составить такой шаблон:
/само.а./ # соответствуют: 'самовар', 'самокат', 'самосад'... # НЕ соответствуют: 'самолюб', 'самогон', 'самоход'...
В регулярном выражении можно задать несколько вариантов образца, любой из которых будет считаться соответствием строки образцу. Варианты образца - это набор возможных альтернатив, разделенных знаком "вертикальная черта" ('|'), который называется "метасимвол альтернатив" (
$text = 'Черная кошка в темной комнате'; # будем искать здесь print "Нашли кошку!" if $text =~ /кот|кошка|котенок/;
Сравнение текста с вариантами образца выполняется слева направо, поэтому, если начало альтернатив совпадает, более длинную альтернативу нужно помещать в начало списка вариантов. Иначе всегда будет найдена более короткая. Значит шаблон в предыдущем примере правильнее записать в виде /котенок|кот|кошка/, чтобы в первую очередь поискать котенка, а затем - кота:
$text = 'Черный котенок в темной комнате'; # ищем здесь print "Нашли котенка!" if $text =~ /кот.нок|кот|кошка/;
Чтобы сделать образец более
return if $command =~ /exit|quit|stop|bye/i;
Если в образце после выбора из нескольких альтернатив применяются другие шаблоны или литералы, то конструкцию выбора нужно заключить в круглые группирующие скобки. Например:
$lotr =~ /(Bilbo|Frodo) Baggins/; # один из хоббитов
С помощью
/[вклрт]от/ # соответствуют: 'вот','кот','лот','рот','тот'
Вот пример шаблона с несколькими классами символов, каждый из которых представляет одну букву в последовательности из четырех символов:
/[мс][ул][хо][ан]/ # соответствуют: 'муха', 'слон' # а также: 'суоа', 'млхн', 'слоа' и так далее
В
[0-9] вместо [0123456789] [A-Z] вместо [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
Указывая несколько
/[0-9a-fA-F]/# соответствуют: '5', 'b', 'D' и так далее
Чтобы включить в символьный
[-.,;:!?] # знаки препинания
[()[\]{}] # скобки: \] представляет скобку ']'
Иногда требуется выразить понятие "все, кроме указанных символов": для этого в описании класса символов сразу после открывающей квадратной скобки ставится метасимвол '^' ). Например, так можно записать шаблоны для "любого символа, кроме знаков препинания" или "любого нецифрового символа":
[^-.,;:!?] # все, кроме этих знаков препинания [^0-9] # не цифры
Чтобы включить в символьный '^', нужно поставить его не первым в списке символов или отменить его специальное значение с помощью символа '\':
[*^] или так: [\^]
Для сокращенной записи классов символов в регулярных выражениях предусмотрены специальные обозначения, состоящие из латинской буквы с обратной косой чертой перед ней. Вот они:
\d - любая десятичная цифра, то есть [0-9] \D - любой символ, кроме цифры: [^0-9] или [^\d] \w - символ, пригодный для записи идентификатора:[a-zA-Z0-9_] \W - противоположность символа \w, то есть [^\w] \s - пробельный символ: пробел, \t, \n, \r или \f \S - любой не пробельный символ, то есть [^\s]
С помощью этих
$text = "Альбом 'Dire Straits'\tГод 1978\tВремя 41:21";
$text =~ m{\s\d\d\d\d\s}; # найдет ' 1978\t'
Записывать несколько
{n} повторяется точно n раз
{n,} повторяется n и более раз
{n,m} повторяется от n до m раз включительно
/\d{5}/ # ровно пять цифр, то есть: \d\d\d\d\d
/\s{1,}/ # один и более пробельных символов
/[A-Z]{1,8}/ # от 1 до 8 заглавных латинских букв
Опишем с применением
символ + \+
код страны: не менее 1 цифры \d{1,}
открывающая скобка ( \(
код города: 3 цифры и более \d{3,}
закрывающая скобка ) \)
номер абонента: от 4 до 7 цифр \d{4,7}
Перед знаками "+", "(" и ")" ставится обратная наклонная черта, чтобы они не воспринимались как
m"\+\d{1,}\(\d{3,}\)\d{4,7}"
Для наиболее часто встречающихся
* повторяется 0 или более раз: то же, что {0,}
? повторяется не более 1 раза: то же, что {0,1}
+ повторяется как минимум 1 раз: то же, что {1,}
Составим
m/\s*\w+[-.,;?]+/ # соответствует, например: ' count--;'
Если \d+ ), за которой может стоять точка ( \.?), причем эта последовательность повторяется ровно четыре раза ({4}):
$pattern = '(\d{1,3}\.){3}\d{1,3}'; # шаблон для IP-адреса
$text = 'address=208.201.239.36,site=www.perl.com';
$text =~ m/$pattern/; # соответствие: '208.201.239.36'
Программисты шутят: "При составлении шаблона главное, чтобы
my $text = 'Какой хороший компакт-диск!'; $text =~ /.+й\s/; # жадный квантификатор # найдено соответствие: 'Какой хороший '
Это произошло потому, что по умолчанию
$text =~ /.+?й\s/; # ленивый квантификатор # найдено соответствие: 'Какой '
Таким же образом можно ограничивать "жадность" и других
Часто нам бывает небезразлично, в каком месте содержимое строки совпадет с шаблоном. Мы бы хотели уточнить: "в начале строки", "в конце слова" и так далее. Для того чтобы более точно задать положение в тексте, где должно быть найдено соответствие, в регулярных выражениях можно указывать так называемые утверждения. Утверждение (
^ позиция в начале строки $ позиция в конце строки (или перед \n в конце строки) \b граница слова: позиция между \w и \W или \W и \w \B любая позиция, кроме границы слова \b
Вот пример шаблонов поиска, где уточняется, что нужно проверить наличие числа в определенном месте строки:
$log = '20060326 05:55:25 194.67.18.73 ... 200 797'; print "Число в начале\n" if $log =~ /^\d+/; print "Число в конце\n" if $log =~ /\d+$/;
Утверждение, которое используется для фиксирования части образца относительно положения в строке, иногда называется якорем (
Когда операция сопоставления находит в строке соответствие указанному регулярному выражению, она присваивает результаты своей работы нескольким специальным переменным:
$` помещается часть строки до найденного соответствия;$ помещается часть строки, соответствующая образцу;$' помещается часть строки после найденного соответствия;$+ помещается последнее найденное совпадение для последнего шаблона в скобках.Если поиск окончился неудачей, то этим переменным новые значения не присваиваются. Посмотрим на примере, что сохранится в этих переменных после поиска такого соответствия:
$htm= "<A HREF='http://regexp.ru/'>Регулярные выражения</A>"; $htm =~ m|HREF=["'](\S+?)["']>|; # поиск URL сайта
При успешном совпадении с шаблоном в специальные переменные будут помещены такие значения:
$` = '<A ' $ = 'HREF='http://regexp.ru/'>' $' = 'Регулярные выражения</A>' $+ = 'http://regexp.ru/'
Значениями этих переменных можно пользоваться при успешном сопоставлении с образцом, например:
print $ if $text =~ m/$pattern/; # выведет соответствие
В регулярном выражении можно указать, что при успешном сопоставлении строки с шаблоном найденные соответствия нужно сохранить для дальнейшей обработки. С этой целью запоминаемые части шаблона нужно заключить в круглые скобки. Это также называется $1, $2 и так далее. Составим
$pattern = q|HREF=["'](\S+?)["']>([^<]+?)</A>|; # шаблон $htm =~ m/$pattern/; # поиск соответствия в $htm # в $1 = 'http://regexp.ru/' # в $2 = 'Регулярные выражения'
Сохраненные совпадения доступны и во время обработки \1, \2 и так далее. Эти переменные называются
my $string = "Уже скоро скоро наступит весна!"; my $pattern = '(\S+)\s+\1'; # (\S+) сохранит значение 'скоро' в \1 $string =~ m/$pattern/; # соответствие: 'скоро скоро'
Операция сопоставления, употребленная в списочном
my $text = 'Начало в 12:25:00.'; # строка с данными my $pattern = '(\d\d):(\d\d):(\d\d)'; # образец для поиска my @time = $text =~ m/$pattern/; # сохраним в массиве my ($hh, $mm, $ss) = $text =~ m/$pattern/; # и в списке
Можно находить любое количество соответствий образцу в одной операции сопоставления. Это делается с помощью модификатора глобального поиска.
До сих пор операция сопоставления прекращала работу и возвращала результат, когда находилось первое соответствие строки указанному шаблону. Если для операции сопоставления указать модификатор /g (
my @numbers = 'Не 12.5, а 25!' =~ /(\d+)/g; # глобальный поиск # в @numbers будет (12, 5, 25)
Ранее в этой лекции уже упоминался модификатор /i, устанавливающий поиск с игнорированием разницы между заглавными и строчными буквами. Перечислим модификаторы для операции сопоставления:
/g - искать в тексте все соответствия образцу (/i - искать соответствие образцу без учета регистра букв (/s - рассматривать текст как одну строку (/m - рассматривать текст как многострочный (Multi-line) с учетом \n ;/o - один раз откомпилировать /x - использовать расширенный Из всех модификаторов, пожалуй, самый интересный - последний, который позволяет записывать
m/ # начало регулярного выражения <A # начало тега: <A [^>]+? # далее могут быть любые символы, кроме > HREF # определение гиперссылки \s*=\s* # знак =, возможно окруженный пробелами ["']? # может быть открывающая кавычка или апостроф ( # начало захвата значения [^'" >]+? # адрес ссылки: все, кроме ',",пробела и > ) # конец захвата значения ['"]? # может быть закрывающая кавычка или апостроф \s* # за которым могут быть пробелы > # конец тега /igx; # конец регулярного выражения # соответствует, например: <a id='ru' href="index.html">
Записанное в таком виде,
Кроме поиска,
$variable =~ s/образец/замена/; # в переменной $variable отыскивается строка 'образец', # и если найдена, то она заменяется на 'замена'
Все, что говорилось до этого про операцию сопоставления, применимо для левой части операции замены, в которой указывается образец поиска. Левая и правая части операции замены интерполируются, поэтому там могут использоваться
$pattern = 'шило'; # образец $replacement = 'мыло'; # замена $text =~ s/$pattern/$replacement/; # поменять 'шило' на 'мыло'
В правой части операции замены могут использоваться
$text = 'мать любит дочь'; $text =~ s/(\S+)\s+(\S+)\s+(\S+)/\3 \2 \1/; # в $text будет 'дочь любит мать'
Для операции замены s/// можно применять все модификаторы, упомянутые для операции сопоставления m//. Например, модификатор /g указывает, что должны быть заменены все найденные в тексте соответствия. Например:
$our_computers =~ s/Windows/Linux/g;
У операции замены есть дополнительный модификатор /e (
$text = 'Бумага воспламеняется при 233C.'; $text =~ s/(\d+\.?\d*)C\b/int($1*1.8+32).'F'/e; # в $text будет: 'Бумага воспламеняется при 451F.'
первым параметром может использоваться
@substrings = split /\s+/, $text; # разбить на части
grep() возвратит
@result = grep /$pattern/, @source; # отобрать элементы
С помощью функции можно применить операцию замены в соответствии с регулярным выражением ко всем элементам массива, например:
@hrefs = ('http://regex.info', 'http://regexp.ru');
map s{http://}{}, @hrefs; # убрать 'http://' из ссылок
| Обозначение | Описание | Примеры |
|---|---|---|
| // | ограничители |
/$ |
| \ | отмена специального значения следующего символа | m{C:\\ |
| () | группировка шаблонов или сохранение значения | /(\w\w\w)+/ |
| | | выбор из нескольких альтернатив | /кошелек|жизнь/ |
| [] | /[0-9a-fA-F]/ | |
| [^] | /[^0-9]/ | |
| . | любой символ, кроме \n (соответствует любому символу, включая \n с модификатором /s) | /(.+)/ |
| \d | десятичная цифра | m{Время=\d+ сек} |
| \D | не десятичная цифра | /(\D*)\d+/ |
| \w | алфавитно-цифровой знак | /\s+\w+\s+/ |
| \W | не алфавитно-цифровой знак | /\W\W\W/ |
| \s | s/\s+/ / | |
| \S | любой символ, кроме пробельного | /\S+/ |
| Утверждения | ||
| ^ | начало строки (соответствует началу каждой строки с модификатором /m) | /^\w+/ |
| $ | конец строки (соответствует концу каждой строки с модификатором /m) | /\d+$/ |
| \b | граница слова (между \w и \W или \W и \w) | /stop\b/ |
| \B | любая |
/stop\B/ |
| \A | только начало строки, даже с модификатором /m | /\A[#]/ |
| \z | только конец строки, даже с модификатором /m | /\w+\z/ |
| \Z | только конец строки или перед \n в конце строки, даже с модификатором /m | /\w+\Z/ |
| \G | ||
| \t \n \r \f \a \b | /[\a\b\f\r\n\t]/ | |
| \0 \x \c \N | /\033\x1F\cZ/ /\x{263a}/ | |
| \l \L \u \U \Q \E | преобразующие последовательности | /\Q$ |
| * *? | любое число повторений, включая 0 (максимальный и |
/\s*/ /\S*?/ |
| + +? | одно и более повторений (максимальный и |
/\d+/ /\D+?/ |
| ? ?? | ноль или одно повторение (максимальный и |
/.?/ /[.a-z]??/ |
| {n} {n}? | ровно n повторений (максимальный и |
/\w{8}/ /\w{5}?/ |
| {n,} {n,}? | n и более повторений (максимальный и |
/\d{2,}/ /\d{5,}?/ |
| {n,m} {n,m}? | от n до m повторений включительно (максимальный и |
/[A-Z]{1,12}/ /[a-z]{0,3}?/ |
Из этой лекции вы узнали о регулярных выражениях далеко не все, но достаточно, чтобы начать свободно пользоваться ими. По мере накопления опыта применения языка
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.