Углубляясь в изучение языка PHP, приходится сталкиваться с новыми понятиями. И чтобы вы хотя бы немного понимали как будут работать дальнейшие коды, которые я буду публиковать на блоге, я решил вам рассказать о такой вещи, как регулярные выражения, которые могут применяться как и в некоторых функциях php, так и в ранее рассматриваемом нами файле .htaccess
.
Обычно регулярные выражения используют для поиска строк или фраз по некому шаблону. Естественно, потом полученные данные обрабатываются и используются в личных целях. Несмотря на своё, кажущуюся однозадачное, назначение, сегодня регулярные выражения очень часто применяются во многих скриптах и движках.
Я уже использовал регулярные выражения в своих кодах, когда предлагал вариант перенаправления RSS ленты на FeedBurner ленту, задавая RewriteRule
. На сегодня, как пример, я использую их для составления ЧПУ с помощью PHP. И способов применения регулярных выражений очень много.
Регулярные выражения — это очень большая тема. В одном посте всё о них не рассказать. Я же вам расскажу только о некоторых возможностях регулярных выражений, которые я чаще всего буду применять в последующих кодах.
Нам необходимо будет составить шаблон для поиска нужных слов, чтобы показать как работают регулярные выражения. Для составления шаблона нам понадобятся специальные метасимволы, которые мы разберём сначала:
^ — начало строки
$ — конец строки
. — любой символ
* — предыдущий символ имеет ноль или более вхождений
+ — предыдущий символ имеет одно или более вхождений
[ и ] — начало и конец группы символов
( и ) — начало и конец группы символов, запоминается функцией
{ и } — начало и конец числа вхождений предыдущего символа
— экранирующий символ, может иметь другие назначение
Некоторые метасимволы, находясь в скобках группы символов, имеют отличное от обычного назначения:
^ — отрицание класса символов
| — условный знак, означающий ИЛИ
— только значение экранирующего символа
Рассматривать другие значения обратного слеша в данном посте не будем. Кому интересно, можете глянуть для чего он ещё используется, глянув на страницу документации.
Для каких функций нам понадобятся регулярные выражения? Таких функций достаточно, которые вы можете просмотреть здесь, я же выделю три самые популярные среди них функций:
preg_match() — выполняет поиск по регулярному выражению до первого совпадения
preg_match_all() — выполняет поиск по регулярному выражению по всему значению заданной переменной/текста
preg_replace() — выполняет поиск по регулярному выражению и производит замену при нахождении соотвествия
Рассмотрим примеры использования трех данных функций и три примера использования регулярных выражений в деле и обработки полученной информации.
Кстати, ещё одно замечание. В данных функциях регулярные выражения должны начинаться и заканчиваться слешом, то есть имеют вид /regexp/. Кроме этого, после завершающего слеша возможно использовать некоторые параметры, называемые модификаторами шаблона. Я расскажу только об одном из них, а все вы можете увидеть на специальной странице документации по PHP.
i — используется, если не важен регистр букв, то есть, в частности, [A-Z] и [a-z] будут означать одно и то же.
Функция preg_match() может возвращать только значение false или true, то есть 0 или 1 соответственно. true означает, что совпадение найдено, а false — обратное. Поэтому чаще всего её используют в условиях. Давайте начнём с самого лёгкого. Возьмём в пример email и сделаем простую проверку правильности его ввода. Она будет не жесткой, поэтому не стоит её использовать, как окончательный вариант.
В данном случае скрипт выведет Right. Подробнее разберем вписанное регулярное выражение.
В email сначала пишется ваше имя, выбранное вами при регистрации, то есть это любое слово, исключающая, в частности, знак @. Код [^@]+ означает, что можно ввести любой, за исключением знака @, и количество символов, отвечающих этому условию, — один и более.
Затем ставиться знак @, который в данном случае я записал как @, то есть использовал символ экранизации, хотя экранизацию можно было и не ставить.
Теперь вводится домен, на котором находится email. Код [^.]+ означает, что можно ввести любые символы, кроме точки. Затем ставить точка, которая обязательно используется вместе с экранизирующим символом, то есть .
. После этого необходимо проверить доменную зону. Обычно доменная зона состоит из 2-4 букв английского алфавита (не берём в расчет доменную зону .РФ и подобные), поэтому мы будем использовать код [a-z]{2,4}
. И для нас не имеет значение регистр, поэтому мы вводим параметр i
после закрытия регулярного выражения.
Функция preg_match_all() проходится по всей переменной и возвращает все совпадения в виде массива. Помните я говорил о группе символов, которую запоминает функция? Вот сейчас вы поймете что я имел ввиду. Возьмём в пример текст, в котором необходимо найти все теги.
Мой сайт цветёт и пахнет, а я живу и радуюсь жизни';
preg_match_all('/<([^>]+)>([^<]+)</[^>]+>/i', $text, $find, PREG_SET_ORDER);
print_r($find);
?>
На выходе получим вот такой массив:
Array
(
[0] => Array
(
[0] => Мой сайт
[1] => a href=»http://mysite/»
[2] => Мой сайт
)
[1] => Array
(
[0] => живу
[1] => b
[2] => живу
)
)
Если вы внимательно посмотрите на регулярное выражение и на полученный результат, то можете заметить, что $find[i][0]
соответствует всему совпадению, $find[i][1]
— первой группе символов, указанных в круглых скобках, $find[i][2]
— второй группе символов. Но третья группа символов [^>]+
не выводится в результате, потому как не заключена в круглые скобки.
Функция preg_replace() делает замену и возвращает переменную уже с произведенными заменами. Причем в данной функции также можно использовать запоминающиеся группы символов для задания нового значения, но задавать их нужно будет в виде \g
или $g
, где g
— номер группы символов или само совпадение при g=0
. Возьмём то же предложение, добавим ещё одну ссылку и с помощью данной функции добавим атрибут nofollow. Заметьте, что во втором параметре функции не используются регулярные выражения, а используются лишь сохраненные группы символов и ваш произвольный текст.
Мой сайт цветёт и пахнет, а я живу и радуюсь жизни';
$replace = preg_replace('/<a([^>]+)>([^<]+)</a>/i', '<a\1 rel="nofollow">\2', $text);
echo $replace;
?></a\1></a([^>
В итоге функция возвратит следующий текст: