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

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

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

    Регулярные выражения

    Когда некоторые говорят, что программы на Perl похожи на бессмысленную кучу символьного мусора, то это впечатление, скорее всего, возникло от вида какого-нибудь длинного регулярного выражения, а они действительно могут выглядеть как загадочный или бессмысленный набор символов, например:

     
    m/<A[^>]+?HREF\s*=\s*["']?([^'" >]+?)['"]?\s*>/ig
     

    (Это всего-навсего шаблон для поиска гиперссылок в HTML-странице.) Но в этой лекции вы узнаете, что регулярные выражения - совсем не ужасные и отнюдь не хаотичные, а наоборот, очень даже логичные и упорядоченные, что употреблять их не так уж сложно, а записывать их можно вполне наглядным способом. Как сказал Джеффри Фридл в своей знаменитой книге, переведенной на русский язык: "Регулярные выражения также можно сравнить с иностранным языком - когда вы начинаете изучать язык, он перестает казаться белибердой".

     

    Начнем с того, что регулярные выражения (regular expression, сокращенно - regexp, regex или RE) - это отдельный язык описания образцов для обработки текста, не имеющий непосредственного отношения к PerlРегулярные выражения использовались в Unixзадолго до создания Perl, а сейчас библиотеки для работы с ними имеются в C++, C#, JavaJavaScriptPHPPythonRubyVisual Basic и других языках. Поддержка регулярных выражений есть в некоторых редакторах, почтовых программах и системах управления базами данных. Другое дело, что широкое распространение Perl в свое время сделало регулярные выраженияпопулярными на разных платформах. А в ходе развития языка Perl была отточена система обозначений для регулярных выражений, ставшая фактическим стандартом. Многие считают, что благодаря Perl регулярные выражения из математической теории превратились в рабочий инструмент тысяч и тысяч программистов. Это произошло потому, что в Perl механизмы работы с регулярными выражениями встроены в ядро языка, поэтому применять их естественно, легко и удобно. А благодаря эффективной реализации "движка" регулярных выражений, в Perl они обрабатываются чрезвычайно быстро. Регулярные выражения выполняют львиную долю работ по обработке текстовой информации и используются в Perl несколькими способами:

     
    • для поиска в тексте строк по определенному образцу;
    • для разделения текста на части по указанному набору разделителей;
    • для извлечения из строки подстрок, соответствующих заданному шаблону;
    • для замены в тексте найденных соответствий на новые значения.
     

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

     

    Поиск соответствий

    Наверное, чаще всего регулярные выражения используются в операции сопоставления (match operator), которая проверяет, соответствует ли текст указанному образцу. Образец (pattern) - это символьная последовательность для сопоставления, записанная в специальной нотации. Простейший образец - это строковый литерал, представляющий собой последовательность символов, которая будет отыскиваться в тексте. В скалярном контексте операция сопоставления возвращает '1', если образец в строке найден, и пустую строку "", если соответствие образцу не найдено. Для указания, к какой строке применить операцию сопоставления, используется операция привязки =~ к строке:

     
    'В строке образец есть' =~ /образец/; # образец найден
     

    Обычно поиск образца выполняется с учетом регистра, но можно игнорировать регистр при сопоставлении строки с образцом, если в операции сопоставления задать модификатор /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 - LearningToothpick 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/; # один из хоббитов
     
    Категория: Лекция | Добавил: mazay (13.05.2014)
    Просмотров: 543 | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Создать бесплатный сайт с uCozCopyright MyCorp © 2024