[ главная ]   [ рейтинг статей ]   [ справочник радиолюбителя ]   [ новости мира ИТ ]



Ответов: 0
25-02-12 07:01







   Web - программирование
PHP


ASP






XML



CSS

SSI





   Программирование под ОС











   Web - технологии








   Базы Данных









   Графика






Данные




Web - программирование / PHP /

Краткое описание регулярных выражений: POSIX и PCRE

Часть 1: Регулярные выражения


Начну с того, что php поддерживает два стандарта регулярных выражений: POSIX и, начиная с четвертой версии, совместимые с Perl. Первый стандарт используется и сервером Apache в mod_rewrite а так же... MySQL в своих запросах (поищите слово "REGEXP" в руководстве по mysql, может сразу поймете, а я об этом позже расскажу). Второй, как ясно из названия, используется в системе perl. Два этих стандарта различаются несильно - во втором есть специальные символы, заменяющие наиболее часто используемые классы символов (например, цифры - d, а буквы и цифры - w) и специальные параметры шаблонов, позволяющие определять регистрозависимость поиска, привязку к концам строк и т.д (в функциях стандарта POSIX регистрозависимость реализована просто: есть функции ereg и ereg_eeplace, есть eregi (insensitive) и eregi_replace). В остальном же оба стандарта совместимы, а приемы написания шаблонов одинаковые.

Если вы работали с Norton/Volkov/Windows Commander или Far, то знаете такую вещь как wildcards. Например: delete c:windows*.* удаляет все файлы из указанной директории. :) В именах файлов особых изощрений делать не приходится, поэтому система простая: символ * означает любой набор символов, в том числе пустой (*.txt), символ ? - любой символ или никакого символа (document?.txt) и еще какие-то обозначения для букв и цифр (я, честно говоря, ими давно не пользовался, поэтому так не вспомню).

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

Итак, задача системы - помимо четко заданных символов ("Вася(.*)Пупкин") позволить указать пользователю поиск заданного количества заданных символов. В приведенном примере с Васей Пупкиным между словами задано любое количество любых символов. Если надо найти шесть цифр, то пишем "[0-9]{6}" (если, например, от шести до восьми цифр, тогда "[0-9]{6,8}"). К чему это все? К тому, что в отличие от wildcard из операционной системы, здесь разделены такие вещи как указатель набора символов и указатель необходимого количества: Вместо набора символов может быть использовано обозначение любого символа - точка, может быть указан конкретный набор символов (поддерживаются последовательности - упоминавшиеся "0-9"). Может быть указано "кроме данного набора символов".

Указатель количества символов в официальной документации по php называется "квантификатор". Термин удобный и не несет в себе кривотолков. Итак, квантификатор может иметь как конкретное значение - либо одно фиксированное ("{6}"), либо как числовой промежуток ("{6,8}"), так и абстрактное "любое число, в т.ч. 0" ("*"), "любое натуральное число" - от 1 до бесконечности ("+": "document[0-9]+.txt"), "либо 0, либо 1" ("?"). По умолчанию квантификатор для данного набора символов равен единице ("document[0-9].txt").

Разумеется, для более гибкого поиска сочетаний эти связки "набор символов - квантификатор" можно объединять в метаструктуры.

Как всякий гибкий инструмент, регулярные выражения гибки, но не абсолютно: зона их применения ограничена. Например, если вам надо заменить в тексте одну фиксированную строку на другую, фиксированную опять же, пользуйтесь str_replace. Разработчики php слезно умоляют не пользоваться ради этого сложными функциями ereg_replace или preg_replace, ведь при их вызове происходит процесс интерпретации строки, а это серьезно потребляет ресурсы системы. К сожалению, это любимые грабли начинающих php-программистов (даже я сам, волею судьбы, сперва увидел в руководстве функцию ereg_replace, а только потом, позже, str_replace).

Пользуйтесь функциями регулярных выражений только если вы не знаете точно, какая "там" строка. Из примеров: поисковый код этого сайта, в котором из строки поиска вырезаются служебные символы и короткие слова а так же вырезаются лишние пробелы (вернее, все пробелы сжимаются: " +" заменяется на один пробел). При помощи этих функций я проверяю email пользователя, оставляющего свой отзыв. Много полезного можно сделать, но важно иметь в виду: регулярные выражения не всесильны. Например, сложную замену в большом тексте ими лучше не делать. Ведь, к примеру, комбинация "(.*)" в программном плане означает перебор всех символов текста. А если шаблон не привязан к началу или концу строки, то и сам шаблон "двигается" программой через весь текст, и получается двойной перебор, вернее перебор в квадрате. Нетрудно догадаться, что еще одна комбинация "(.*)" означает перебор в кубе, и так далее. Возведите в третью степень, скажем, 5 килобайт текста. Получается 125 000 000 000 (прописью: сто двадцать пять миллиардов операций). Конечно же, если подходить строго, там стольких операций не будет, а будет раза в четыре-восемь меньше, но важен сам порядок цифр.

Итак, принципы, достоинства и недостатки описаны, теперь надо переходить к конкретике. Два (возможно, сразу следующих) выпуска будут посвящены двум стандартам регулярных выражений - POSIX и PCRE. Описание базовых принципов и понятий работы регулярных выражений.

Часть 2: POSIX


Продолжаем наш разговор. Предыдущий выпуск был вводным, теорией. Сегодня как бы основная часть рассказа — стандарт POSIX. В следующем выпуске я опишу различия, вернее сказать надстройки стандарта совместимого с perl. Итак, обо всем по порядку.
Набор символов


.        точка        любой символ
[<символы>]        квадратные скобки        класс символов ("любое из")
[^<
символы>]                 негативный класс символов ("любое кроме")
-       
тире        обозначение последовательности в классе символов ("[0-9]" — цифры)


Особо объяснять ничего не нужно. Разве что следующее: не пользуйтесь классом символов для обозначения всего лишь одного (вместо "[ ]+" вполне сойдет " +"). Не пишите в классе символов точку — это ведь любой символ, тогда другие символы в классе будут просто лишними (а в негативном классе получится отрицание всех символов).


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


Это, как я уже писал, указатель количества заданных символов. Квантификатором можно указать как конкретное значение, так и пределы. Если число заданных подпадает под пределы квантификатора, фрагмент выражения считается совпавшим с разбираемой строкой. Синтаксис: {<количество>} либо {<минимум>, <максимум>}

Если нужно указать только необходимый минимум, а максимума нет, просто ставим запятую и не пишем второе число: "{5,}" ("минимум 5"). Для наиболее часто употребляемых квантификаторов есть специальные обозначения:


*        "звёздочка" или знак умножения        {0,}
+       
плюс        {1,}
?       
вопросительный знак        {0,1}

На практике такие символы используются чаще, чем фигурные скобки.
Якоря
^        привязка к началу строки
$        привязка к концу строки


Эти символы должны стоять соответственно в самом начале и в самом конце строки. Чтобы интерпретатор корректно понял символ $ в конце, желательно добавить к нему обратный слэш: ereg("foo$", $bar)


Структура


Сейчас будет сложное описание, мне оно и самому не нравится. Эта вещь необходима для сложных запросов. Например, вам надо, чтобы в тексте были либо только маленькие буквы, либо только большие, либо только цифры. Класс символов "[a-zA-Z0-9]" не подходит. Тогда пишем такое:


if (ereg("[a-z]+|[A-Z]+|[0-9]+", $text)) ...


Вертикальная черта — знак "или" регулярных выражений (знака "и", естественно, не существует — это и есть само регулярное выражение). Разделенные вертикальной чертой шаблоны в официальной документации называются альтернативными ветвями (это подразумевает ветвление, т.е. наличие вложенных альтернативных ветвей). Программа сравнивает со строкой все ветви (проходясь по их ряду слева направо), до первого совпадения (это важно учесть, если у вас сложное выражение со вложенными ветвями). Для разделения уровней и отделения этого дерева альтернатив от остального шаблона используются обычные скобки. Если те же большие/маленькие буквы/цифры надо искать внутри контейнера тегов:


if (ereg("<tag>([a-z]+|[A-Z]+|[0-9]+)</tag>", $text)) ...


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


ereg_replace("<a href=([^>]+)>[^<]+</a>", "




Комментарии

 Ваш комментарий к данному материалу будет интересен нам и нашим читателям!



Последние статьи: Web - программирование / PHP /

GTK+: перспективы развития
02-03-2010   

Библиотека GTK+ прошла долгий путь развития и сейчас очень популярна. GNOME, одна из ведущих оконных сред, использует GTK+ почти исключительно, GIMP построен на GTK+, множество коммерческих разработчиков ПО, таких как Abobe, NVidia и VMware, решили использовать эту библиотеку в качестве графической основы для своих продуктов... подробнее

Кол. просмотров: общее - 4944 сегодня - 0

Новостной портал
13-11-2009   

Slashdot.org – популярный новостной портал с посещаемостью 50 млн. человек в месяц. Авторы проекта добились такого успеха, предоставляя пользователям свежие и интересные новости из мира IT... подробнее

Кол. просмотров: общее - 4853 сегодня - 0

Параллельное выполнение скриптов может нарушить целостность информации в файлах
13-11-2009   

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

Кол. просмотров: общее - 4629 сегодня - 0

No spam.php
10-11-2009   

...и снова о спаме. Кто о нем только не писал, и все писали, что это плохо и ай-яй-яй. Я не буду оригинальничать, и тоже скажу – это плохо. Это ай-яй-яй. Как бороться со спамерами со своей стороны... подробнее

Кол. просмотров: общее - 4687 сегодня - 0

Начинаем работу с рисунками в php для Windows
10-11-2009   

Эта статья даст вам общее представление о том, как создавать, обрабатывать и выводить рисунки в PHP4 для Windows... подробнее

Кол. просмотров: общее - 4661 сегодня - 0



  WWW.COMPROG.RU - 2009-2012 | Designed and Powered by Zaipov Renat | Projects