Регулярные выражения в 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, покупка SSL сертификатов, доработка сайтов, сопровождение сайтов, разработка сайтов, техподдержка сайтов
Была ли эта статья полезна? Есть вопрос?
Cмотрите другие статьи: