KnigaRead.com/

Михаил Шохирев - Язык программирования Perl

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Михаил Шохирев, "Язык программирования Perl" бесплатно, без регистрации.
Перейти на страницу:

Обычно поиск образца выполняется с учетом регистра, но можно игнорировать регистр при сопоставлении строки с образцом, если в операции сопоставления задать модификатор /i (ignore case). Для корректной обработки национальных букв должна быть включена прагма use locale. Например:


use locale; 'В строке образец есть' =~ /Образец/; # образец НЕ найден! 'В строке образец есть' =~ /Образец/i; # образец найден


Результат операции сопоставления в тексте можно присвоить скалярной переменной или использовать в любой из условных конструкций, например:


$text = 'Черный кот в темной комнате'; # ищем в этом тексте $found = $text =~ /кот/; # в $found будет '1' print 'Кошки нет!' unless $text =~ /кошка/; # вернет ''


Последнее предложение можно переписать, применив операцию отрицательной привязки к строке (!~), которая инвертирует (меняет на обратный) результат операции сопоставления:


print 'Кошки нет!' if $text !~ /кошка/;# вернет '1'


Если операция привязки к строке не используется, образец отыскивается в переменной по умолчанию $_. Выражение перед поиском интерполируется, поэтому весь образец поиска или его часть может содержаться в переменной. Например:


$_ = 'Счастье - это когда тебя понимают.'; # переменная поиска $pattern = 'Счастье'; # образец для сопоставления print "$pattern найдено!" if /$pattern/;


В составе образца поиска могут применяться не только переменные, но и escape-последовательности, известные нам из лекции 2, например:


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 - Learning Toothpick Syndrome). В приводимых до сих пор примерах операцию сопоставления с литералом в качестве образца вполне можно заменить вызовом функции index(). Самое интересное начинается тогда, когда в образце поиска применяются метасимволы для сопоставления с шаблоном.

Очень часто требуется искать в тексте не конкретные строки, а символьные последовательности, определенные приблизительно: "число в скобках", "четвертое слово с начала строки", "список из пар имя = значение, разделенных запятыми" и тому подобное. В таких случаях в качестве аргумента поиска задается шаблон, который описывает такую последовательность. Шаблон - это образец, в котором, помимо литеральных значений, содержатся метасимволы. Метасимволы (metacharacter) - это знаки, имеющие специальное значение при записи образцов. Вот какие метасимволы применяются при записи регулярных выражений:


{} [] () ^ $ . | * + ?


При необходимости включить в образец поиска один из этих знаков не как метасимвол, а как обыкновенный символ, нужно отменить его особое значение ("экранировать"), поставив перед ним обратную косую черту (backslash):


$text =~ m"." # содержится ли в тексте точка?


Как метасимвол точка обозначает в регулярном выражении один любой символ, кроме знака перевода новой строки (n). Например, для поиска похожих слов можно составить такой шаблон:


/само.а./ # соответствуют: 'самовар', 'самокат', 'самосад'... # НЕ соответствуют: 'самолюб', 'самогон', 'самоход'...


В регулярном выражении можно задать несколько вариантов образца, любой из которых будет считаться соответствием строки образцу. Варианты образца - это набор возможных альтернатив, разделенных знаком "вертикальная черта" ('|'), который называется "метасимвол альтернатив" (alternation metacharacter). Поиск считается успешным, если найдено соответствие любой из альтернатив, например:


$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]


С помощью этих метасимволов можно составлять гораздо более интересные образцы. Например, проверим, содержится ли в тексте число из четырех цифр, окруженное любыми пробельными символами:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*