Регулярные выражения в PHP часть 3 (preg_match)

В предыдущей части статьи "Регулярные выражения в PHP (preg_replace) часть 2" мы говорили исключительно о функции preg_replace, которая заменяет часть строки. Но есть ещё функция preg_match, которая выполняет поиск в строке по регулярному выражению. Эта функция возвращает 1, если хотя бы одно совпадение найдено и 0, если не было найдено ни одного. Приведём пример использования:
<?php 
   echo preg_match('#ше#u', 'Тише, мыши, кот на крыше');  // вернёт 1
   echo preg_match('#сыр#u', 'Тише, мыши, кот на крыше');  // вернёт 0
?>
Функция preg_match применяется нечасто, потому что всего лишь говорит есть или нет подстрока. Но есть ещё функция preg_match_all, которая имеет три параметра и находит все совпадения, записывая их в третий параметр. Звучит сложно, но посмотрим на практике, что это значит:
<?php 
   $a = array();
   $b = preg_match_all('#\b..ш.#u', 'Тише, мыши, кот на крыше', $a); 
   echo '<pre>';
   print_r($a);
   echo '</pre>';
?>
В результате выполнения такого кода переменная $b станет равна 2, а в переменной $a будет массив с найденными совпадениями. Результат будет такой:
Array
(
   [0] => Array
   (
      [0] => Тише
      [1] => мыши
   )
)

Карманы

У функции preg_match_all есть возможность выгружать не только найденные совпадения, но и найденные вариации, которые называются карманами. Эти карманы появляются, если использовать скобки ( ) Приведём пример:
<?php 
   $a = array();
   $b = preg_match_all('#\bс(ы+)р\b#iu', 'Сыр, сыыр, сыыыр', $a); 
   echo '<pre>';
   print_r($a);
   echo '</pre>';
?>
В этом примере переменная $b примет значение 3, а в переменной $a будет массив:
Array
(
   [0] => Array
   (
      [0] => Сыр
      [1] => сыыр
      [2] => сыыыр
   )

   [1] => Array
   (
      [0] => ы
      [1] => ыы
      [2] => ыыы
   )
)
В первом массиве будут содержаться найденные совпадения, а во втором содержимое первого кармана. Карманов может быть несколько, в зависимости от количества скобок ( ), которые использовались в регулярном выражении.

Скобки автоматически создают карманы. Если же нужно отказаться от создания кармана, то нужно добавить в начало скобок символы "?:". Тогда в примере выше регулярное выражение примет такой вид "'#\bс(?:ы+)р\b#iu'".

Карманы и preg_replace

Функция preg_replace тоже умеет использовать карманы. Их можно подставлять во второй параметр функции, используя порядковый номер и знак $. Таким образом можно заменять части строки так, что содержащиеся в кармане части будут подставляться на замену.
<?php 
   echo preg_replace('#([а-я]+), ([а-я]+), ([а-я]+)#iu', '$3, $1, $2', 'Сыр, мышь, кот'); 
?>
В первый карман попадёт слово "Сыр", во второй "мышь", а в третий "кот". По правилу '$3, $1, $2' результат будет иметь содержимое из 3 кармана, затем запятую и пробел, потом содержимое 1 кармана с запятой и пробелом, и в конце содержимое 2 кармана. Результат будет такой:
кот, Сыр, мышь
Напомним, что регулярными выражениями необходимо использовать только в том случае, если нет никакого другого способа решения.

Ошибки в регулярных выражениях - это очень частое явление. Поэтому прибегайте к этому инструменту только в самых-самых безвыходных ситуациях, когда всё остальное уже опробовано.
Можно обращаться к содержимому кармана непосредственно в регулярном выражении. То есть в карман заносятся данные и тут же достаются. Для этого необходимо поставить слеш \ и затем номер кармана непосредственно в регулярном выражении:
<?php 
   echo preg_replace('#([а-я]+)\1#u', '!', 'Сыр, сыыр, сыыыр'); 
?>
В приведённом примере выражение "#([а-я]+)\1#" сначала заносит в карман любую букву, а котом достаёт её же и ставит после найденной. Эффект получается такой, как будто мы находим повторяющуюся два раза букву и делаем её замену:
Сыр, с!р, с!ыр

Позитивный и негативный просмотр

Функцией preg_replace найденное выражение заменяется полностью на второй параметр. Но что делать, если нам не надо заменять всё найденное, а только часть? Для этого есть позитивный и негативный просмотр.

Представьте, что нужно заменить слово, не заменяя первую букву. Приведём пример реализации:
<?php 
   echo preg_replace('#(?<=к)от#u', 'отята', 'Тише, мыши, кот на крыше'); 
?>
Результат будет такой:
Тише, мыши, котята на крыше
Хоть буква "к" и стоит в регулярном выражении, но она стоит в специальных скобках (?<=к), которые проверяют наличие буквы, но не подставляют её на замену. Такие скобки называются позитивным просмотром. Можно сделать позитивный просмотр и в конце строки:
<?php 
   echo preg_replace('#крыш(?=е)#u', 'сыр', 'Тише, мыши, кот на крыше'); 
?>
Позитивный просмотр (?=е) проверяет, есть ли в конце строки буква "е". Происходит замена и получается такая строка:
Тише, мыши, кот на сыре
Теперь рассмотрим оба примера (просмотр в начале и в конце строки), но в негативном смысле. Негативный просмотр - это противоположность к позитивному и создаётся с помощью скобок (?<! ) для поиска символа вначале и (?! ) в конце. То есть он проверяет нет ли такого символа:
<?php 
   echo preg_replace('#(?<!Ти)ше#u', 'шке', 'Тише, мыши, кот на крыше'); 
   echo preg_replace('#сыр(?!ок)#iu', 'Мышка', 'Сыр, сырок'); 
?>
Результат будет такой:
Тише, мыши, кот на крышке
Мышка, сырок
MouseDC.ru - хостинг, виртуальный хостинг, покупка доменов, проверка доменов, WHOIS, курсы создания сайтов, вебинары по созданию, курсы разработки сайтов, доработка сайтов, сопровождение сайтов, разработка сайтов, техподдержка сайтов
Была ли эта статья полезна? Есть вопрос?
Cмотрите другие статьи: