PHP в деталях

       

Регулярные выражения. Часть 3. PCRE.


DL
16.2.2001

И вот, наконец, серия выпусков про регулярные выражения подходит к концу. Поговорим о регулярных выражениях совместимых с Perl (Perl compatible regular expressions? PCRE).

Самое главное их преимущество перед POSIX, как мне уже подсказывают ? возможность "жадного" поиска. Вопросительный знак в PCRE выступает еще и как минимизатор квантификатора:

.*?

Найдет минимальную подходящую строку. Вроде бы ничего особенного? Нет, это очень особенная вещь. Например, какой пример я приводил в прошлом выпуске про печатную версию текста?

$text = ereg_replace("<a +href=([^>]+)>[^<]+</a>", "\\0 [\\1]", $text);

То есть, внури ссылки не должно быть тегов (например "<a href=...><b>...</b></a>"). Если же сделать так:

$text = ereg_replace("<a +href=([^>]+)>.*</a>", "\\0 [\\1]", $text);

Тогда мы получим... Правильно, весь текст между началом первой и концом последней ссылки.

Все проблемы снимает жадный поиск.

$text = preg_replace("/<as+href=(.*?)>.*?</a>/", "\\0 [\\1]", $text);

Программа подберет для всех ссылок минимальную подходящую строку, т.е. только до тега "</a>". Описывать значение такой особенности PCRE нет смыла ? оно огромное. :) Идем дальше.

Цифры теперь можно обозначить не как "[0-9]", а просто "\d". Не-цифры ("[^0-9]") как "\D". Очень удобно. Вот остальные обозначения:



\w[a-z0-9]
\W[^a-z0-9]
\s[ ]
\S[^ ]

Рекомендую заглянуть в выпуски про поиск ? там эти символы используются.

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

iрегистронезависимый поиск
mмногостроковый режим. По умолчанию PCRE ищет сопвадения с шаблоном только внутри одной строки, а символы "^" и "$" совпадают только с началом и концом всего текста. Когда этот параметр установлен, "^" и "$" совпадают с началом и концом отдельных строк.
sсимвол "." (точка) совпадает и с переносом строки (по умолчанию ? нет)
Aпривязка к началу текста
Eзаставляет символ "$" совпадать только с концом текста. Игнорируется, если установлен парамерт m.
UИнвертирует "жадность" для каждого квантификатора (если же после квантификатора стоит "?", этот квантификатор перестает быть "жадным").
<
Естественно, регистр в параметрах имеет значение. Остальное о них можно прочесть в [].

Теперь о функциях PCRE.

Функция [] в отличие от ereg ищет только первое совпадение. Если нужно найти все совпадения и как-то обработать их результаты (но не напрямую через ) [], нужно пользоваться []. Параметры этой функции те же.

Из полезного отмечу функцию [], которая вставляет слэши перед всеми служебными символами (например, скобками, квадратными скобками и т.п.), чтобы те воспринимались буквально. Если у вас есть какой-либо ввод информации пользователем, и вы проверяете его через PCRE, лучше перед этим закомментировать служебные символы в пришедшей переменной (мало ли что он там напишет, это ведь по определению злобный хакер).

Это все, что я могу сказать про регулярные выражения. Дальше ? только искусство комбинирования строк и написания алгоритмов.

Помнится, в одном из пришлых выпусков я описал рассыльщик почты на классах. Теперь я добавил туда хранение адресов в файлах и подтверждение подписки. Разумеется, различные проверки адресов, получение списка активных и тому подобное ? все работает на PCRE. К сожалению, времени на тестирование и доводку не было, рассыльщик "сырой".


Содержание раздела