При проверке значений строк зачастую требуется не установить точное совпадение с искомым значением, а найти соответствие некоторому шаблону, приблизительно характеризующему строку. Так, при описании человека говорят, что он высокого роста. Эта характеристика не точна, но во многих случаях позволяет исключить наверняка неподходящих людей. Такого рода шаблоны в PHP составляют с помощью регулярных выражений.
Язык регулярных выражений – это язык составления шаблонов. В PHP поддерживаются два стандарта шаблонов – POSIX-совместимые регулярные выражения и Perl-совместимые регулярные выражения (PCRE).
Рассмотрим формирование шаблонов с помощью языка PCRE.
Шаблон регулярного выражения – это строка, состоящая из простого текста и метасимволов, которые позволяют находить соответствие нескольким символам одновременно:
\d соответствует цифре,
\D соответствует нецифровому символу,
\s соответствует пробельному символу, символу табуляции, символу новой строки,
\S не соответствует вышеназванным символам,
\w соответствует латинской или русской букве, цифре или подчеркиванию,
\W соответствует любому символу, кроме русской или латинской буквы, цифры или подчеркивания,
. любой символ, кроме символа новой строки.
Для проверки на соответствие регулярному выражению используется функция:
Функция возвращает 1 , если найдет соответствие шаблону в строке хотя бы один раз, в противном случае возвращает 0. Шаблон записывается как переменная строкового типа, а само значение шаблона помещается в разделители – знаки деления (прямые слэши):
$str = ”abc5dr35f”;
//определяем наличие хотя бы одной цифры встроке
$pattern = ’/\d/’ ;
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
Базовые классы метасимволов предназначены для поиска одного единственного символа в строке. Для какого-либо полезного их применения язык регулярных выражений надо дополнить обозначениями того, сколько раз метасимволы могут встречаться в строке – операторами счетчиков символов (квантификаторами):
* повторение символа ноль или более раз /\w*/
+ повторение символа один или более раз /\w+/
? повторение предыдущего символа ноль или один раз /\d?/
{n} ровно n вхождений символа /\d{5}/
{n,}n или больше вхождений символа /\w{3,}/
{,n}n или меньше вхождений символа /\d{,5}/
{m,n} не менее чем m и не более чем n вхождений символа /\d{2,5}/
Найдем в исходной строке пять цифр, за которыми следует дефис, а затем еще четыре цифры:
$str = ”abc12345-1234dr35f”;
$pattern = ’/\d{5}-\d{4}/’;
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
При этом символы, не входящие в число метасимволов, например дефис, рассматриваются просто как текстовый символ, который нужно найти. Если поставить в этой строке между пятеркой и дефисом пробел, то функция не найдет совпадения с шаблоном.
Функция preg_match() ищет совпадение с шаблоном по всему тексту. Если необходимо, чтобы шаблон находился именно в начале исходной строки, то необходимо добавить символ привязки к начальной позиции ^:
$str = ”13312345-1234dr35f”;
$pattern = ’/^\d{5}/’; // пять цифр в начале строки
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
На конец строки указывает метасимвол $ :
$str = ”13312345-1234dr12345f”;
$pattern = ’/\d{5}$/’; // пять цифр в конце строки
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 0
$str = ”13312345-1234dr12345”;
$pattern = ’/\d{5}$/’; // пять цифр в конце строки
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
Если необходимо найти строку, состоящую исключительно из символов, соответствующих шаблону, то необходимо использовать эти метасимволы совместно:
$str = ”13312345-1234dr12345”;
$pattern = ’/^\d{5}$/’; // только пять цифр в строке
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 0
$str = ”1234512345”;
$pattern = ’/^\d{5}$/’; // только пять цифр в строке
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 0
$str = ”54321”;
$pattern = ’/^\d{5}$/’; // только пять цифр в строке
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
Можно создавать собственныеклассы символов, помещая символы в квадратные скобки. Допускается указывать диапазоны значений. Например, чтобы создать класс для обозначения шаблона соответствия одной из цифр от 3 до 5 , можно использовать [3-5]:
$str = ”4678891”;
$pattern = ’/[3-5]{1}[6-8]{4}/’;
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
Искали одно вхождение цифр от 3 до 5 и четыре вхождения цифр от 6 до 8. Нашли строку “46788”.
$str = ”ABC dkfd884sxRST”;
$pattern = ’/[a-z348]+/’;
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
Искали строчные латинские буквы или цифры 3, 4, 8. Нашли строку “dkfd884sx”.
Если не поставить знак «плюс» (повторение символов один или более раз) после закрывающей квадратной скобки, то будет найдена строка, состоящая только из одной буквы – “d”.
Символ вертикальной черты | используется для разделения альтернативных вариантов. Например, шаблон ‘город|село’ означает, что ищется любое слово - ‘город’ или ‘село’:
$str = ”Я проживаю в городе Иркутске”;
$pattern = ’/город|село/’; // или город или село
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
Допустимо указывать любое количество альтернатив. В процессе поиска соответствия просматриваются все перечисленные альтернативы слева направо до первого найденного соответствия.
Шаблоны могут работать по-разному в зависимости от модификаторов, которые добавляются после закрывающего шаблон разделителя. Самый известный модификатор:
i (ignore case)не различать строчные и прописные буквы:
$str = ”Я НЕ ВЫКЛЮЧИЛ CAPS LOCK”;
$pattern = ’/[а-я]/i’; // c модификатором
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 1
$str = ”Я НЕ ВЫКЛЮЧИЛ CAPS LOCK”;
$pattern = ’/[а-я]/’; // без модификатора
$value = preg_match($pattern, $str);
echo '$value = ', "$value <BR>"; // $value = 0
Можно не только узнать, имеется ли в исходной строке подстрока, соответствующая шаблону, но и получить эту подстроку. Для этого в качестве третьего параметра функции preg_match() задается имя массива. Нулевой элемент этого массива-списка будет содержать найденную подстроку:
$str = ”Злой браконьер охотился на зайчиков”;
$pattern = ’/конь|лошадь/i’; // или конь или лошадь
$value = preg_match($pattern, $str, $matches);
echo '$value = ', "$value <BR>"; // $value = 1
echo $matches[0], “<BR>”; // конь
Для разбиения строки на отдельные слова используется функция preg_split(). Ее действие аналогично действию функции explode(), но в качестве разделителей слов можно использовать не один, а несколько различных символов. Функция возвращает массив-список:
$fruit = ”яблоки, апельсины, персики и лимоны”;
$pattern = ’/, | и /’; // запятая с пробелом или и в пробелах
По умолчанию регулярные выражения соответствуют максимально возможному количеству символов в строке:
/к.*т/ - поиск строки произвольной длины, начинающейся буквой к и заканчивающейся последней найденной буквой т (не в смысле последним символом в строке):
$str = “кот кит корт кант”;
$pattern = ’/к.*т/’;
$value = preg_match($pattern, $str, $matches);
echo '$value = ', "$value <BR>"; // $value = 1
echo $matches[0], “<BR>”; // кот кит корт кант
Если после любого квантификатора поставить знак вопроса ? , то можно ограничить количество найденных символов:
/к.*?т/ - поиск строки произвольной длины, начинающейся буквой к и заканчивающейся первой найденной буквой т:
$str = “кот кит корт кант”;
$pattern = ’/к.*?т/’;
$value = preg_match($pattern, $str, $matches);
echo '$value = ', "$value <BR>"; // $value = 1
echo $matches[0], “<BR>”; // кот
Можно выявить не только найденную подстроку, но и любые ее фрагменты. Для этого внутри шаблона эти фрагменты необходимо заключить в круглые скобки (организовать подшаблоны):
$str = ”Дата моего рождения – 19.09.1949”;
$pattern = ’/([0-9]{2}).([0-9]{2}).([0-9]{4})/’; //дата рождения
Таким образом, в нулевой элемент массива снова помещается найденная подстрока, а в остальные элементы – фрагменты этой подстроки согласно номерам подшаблонов (по номеру открывающей круглой скобки перед подшаблоном):
([0-9]{2}) - первый подшаблон,
([0-9]{2}) - второй подшаблон,
([0-9]{4}) - третий подшаблон.
Регулярные выражения также позволяют выполнять замену фрагментов строк. Для этого используется функция :
Вторым аргументом вместо подстроки-замены могут быть ссылки на подшаблоны вида \n (n – номер подшаблона):
Шаблон в этом примере составлен так, что сначала в тексте ищется слово “всего” – первый подшаблон (1), потом после пробела могут идти одна или несколько букв или цифр, а затем “слова” – второй подшаблон. Эти подшаблоны упоминаются во втором аргументе в виде цифр, перед которыми стоит слэш. Функция находит соответствие шаблону в тексте и заменяет найденный фрагмент значением второго аргумента, подставив в него найденные подшаблоны.
В PHP можно создавать функции в процессе выполнения сценария. Поскольку такие функции не имеют самостоятельных имен (ссылку на них сохраняют в переменных или передают другим функциям), она называются автономными.
Для создания автономных функций предусмотрена функция:
Внимание! Формальные параметры функции create_function() заключаются в одиночные кавычки! Перед закрывающей скобкой тела функции } обязательно поставить точку с запятой!
Автономные функции используются в тех случаях, когда стандартной функции PHP нужно передать функциюобратного вызова. Такая функция пишется пользователем и предназначается для неоднократного вызова из функции, которой ее передают.