Работа с функцией preg_replace_callback

Пришлось работать с функцией preg_replace_callback. Это весьма сильная вещь, так как позволяет быстро и изящно обработать сложные текcтовые конструкции. Отличие данной функции от preg_replace состоит в том, что можно передать свою собственную функцию с нетривиальной логикой для обработки текстовых совпадений.
Стоит отметить, что в обеих функциях есть возможность обращаться к совпадениям, найденным регулярным выражениям как к переменным. $k - совпадение с k-ой подмаской в регулярке (также можно обращаться \\k- однако первый вариант предпочтительней. ) $0 - совпадение со всем выражением.

Например следующий код

 $text = preg_replace("#<pre>(.*?)</pre>#", "<strong>$1</strong>", $text);

Заменит теги <pre> на теги <strong> , но сохранит все, что между ними.
Однако недостаток этой функции в том, что нельзя передать $1 в другую функцию для более сложной обработки. Тут-то и пригодится функция preg_replace_callback. В нее вместо строки, на которую надо заменять совпадение можно передать свою функцию, которая получает массив всех совпадений с подмасками, где номер индекса - номер подмаски, 0 - все выражение. Рассмотрим пример.

    $text = preg_replace_callback('#<pre(?:.*?)>(.*?)</pre>#si', function($matches)
    {
         return str_replace($matches[1], htmlentities($matches[1]), $matches[0]);
    }, $text);

Данный код закодирует все html-теги внутри <pre>. Стоит заменить, что значение возвращаемое функцией переданной в preg_replace_callback, используется для замены строки совпавшей со всем регулярным выражением, поэтому мы возвращаем строку $matches[0] в которой заменили подстроку $matches[1] на закодированный текст. Соотвественно функцию передаваемую в preg_replace_callback (это наш callback) можно объявить отдельно, тогда надо просто передать ее имя:

    $text = preg_replace_callback('#<pre(?:.*?)>(.*?)</pre>#si', "myFunction", $text);
vedro-compota's picture

Спасибо за интересный обзор)
Интересно, что именно preg_replace_callback используется иллюстрации работы анонимных функций в php - сразу же наткнутлся на неё когда пошёл в поиск, чтобы проверить. что то что используется в этой конструкции называется анонимной функций:

$text = preg_replace_callback('#<pre(?:.*?)>(.*?)</pre>#si',
 function($matches) // анонимная функция (безымянная)
{
     return str_replace($matches[1], htmlentities($matches[1]), $matches[0]);
}, $text); 

_____________
матфак вгу и остальная классика =)