Четверг, 28.03.2024, 20:58
Приветствую Вас Гость | RSS
Главная | Лекции | Регистрация | Вход
Меню сайта
Форма входа
Логин:
Пароль:
Категории раздела
Лекция [24]
Мини-чат
100
Поиск
Наш опрос
Оцените мой сайт
Всего ответов: 2
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Программирование Perl
    Главная » Статьи » Лекция » Лекция

    Лекция 8.2: Регулярные выражения

    Классы символов

    С помощью метасимволов можно обозначить в шаблоне один символ из заданного набора. Для этого нужно определить класс символов, указав в квадратных скобках набор символов, включаемых в классКлассы символов похожи на шаблон с вариантами, в котором альтернативами могут быть только отдельные символы. Ради примера запишем шаблон для слов, отличающихся первой буквой из указанного набора:

     
    /[вклрт]от/ # соответствуют: 'вот','кот','лот','рот','тот'
     

    Вот пример шаблона с несколькими классами символов, каждый из которых представляет одну букву в последовательности из четырех символов:

     
    /[мс][ул][хо][ан]/ # соответствуют: 'муха', 'слон'
    # а также: 'суоа', 'млхн', 'слоа' и так далее
     

    В классе символов вместо перечисления можно указывать диапазон от начального до конечного символа, разделенных дефисом:

     
    [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'
     

    Записывать несколько метасимволов подряд для указания в шаблоне последовательности из однотипных символов утомительно и неудобно, да и ошибиться при этом легко. Облегчить жизнь составителям регулярных выражений помогают квантификаторы.

    Квантификаторы

    Квантификатор (quantifier) - это обозначение числа повторений предыдущего шаблона при поиске соответствия. Количество повторений может задаваться одним или парой десятичных чисел в фигурных скобках:

     
    {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--;'
     

    Если квантификатор нужно применить к нескольким шаблонам, то нужно сгруппировать шаблоны, заключив их в круглые скобки. Составим регулярное выражение для поиска IP-адреса, которое находит число, состоящее из одной цифры и более ( \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/; # жадный квантификатор
    # найдено соответствие: 'Какой хороший '
     

    Это произошло потому, что по умолчанию квантификаторы подразумевают максимальную последовательность символов, соответствующих указанному шаблону. Такое поведение квантификаторов называется "жадным" (greedy quantifier). Чтобы заставить квантификатор вести себя не "жадно", а "лениво" (lazy quantifier), нужно поставить сразу после него символ '?'. Тогдаквантификатор будет описывать минимальную последовательность символов, соответствующих образцу. Исправленный с учетом этого образец найдет то, что нужно:

     
    $text =~ /.+?й\s/; # ленивый квантификатор
    # найдено соответствие: 'Какой '
     

    Таким же образом можно ограничивать "жадность" и других квантификаторов, заставляя их прекращать поиск как можно раньше, что обычно и требуется в большинстве ситуаций.

     

    Утверждения

    Часто нам бывает небезразлично, в каком месте содержимое строки совпадет с шаблоном. Мы бы хотели уточнить: "в начале строки", "в конце слова" и так далее. Для того чтобы более точно задать положение в тексте, где должно быть найдено соответствие, в регулярных выражениях можно указывать так называемые утверждения. Утверждение (assertion) не соответствует какому-либо символу, а совпадает с определенной позицией в тексте. Поэтому их можно воспринимать как мнимые символынулевого размера. Чаще всего используются следующие утверждения (другие приведены в таблице 8.1):

     
    ^ позиция в начале строки
    $ позиция в конце строки (или перед \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+$/;
     

    Утверждение, которое используется для фиксирования части образца относительно положения в строке, иногда называется якорем (anchor). Якори применяются, чтобы указать, в каком именно месте строки нужно искать соответствие образцу.

    Категория: Лекция | Добавил: mazay (13.05.2014)
    Просмотров: 366 | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Создать бесплатный сайт с uCozCopyright MyCorp © 2024