preg_replace_callback странное поведение

#php #regex #preg-replace-callback

#php #регулярное выражение #preg-replace-обратный вызов

Вопрос:

Я не могу понять, почему preg_replace_callback обрабатывает такой шаблон

     $article = "{{test1}} {{test2}}";

    $article = preg_replace_callback('{{(.*?)}}', 'handlePattern', $article);

    function handlePattern($matches) {
        echo "matches = " . print_r($matches, true);

    }
  

И он выводит этот результат

     matches = Array
(
    [0] => {{test1}
    [1] => {test1
)
matches = Array
(
    [0] => {{test2}
    [1] => {test2
)
  

Но я ожидаю, что это должно быть так

 matches = Array
(
    [0] => {{test1}}
    [1] => test1
)
matches = Array
(
    [0] => {{test2}}
    [1] => test2
)
  

Как я могу получить содержимое внутри {{ }}?

Ответ №1:

В следующем выражении внешние фигурные скобки интерпретируются как разделители регулярных выражений

'{{(.*?)}}'

На самом деле вы можете использовать любой разделитель. Например, следующее имеет тот же эффект:

'/{(.*?)}/'

Поэтому вы должны использовать разделители в своем выражении, например:

'/{{(.*?)}}/'

Кроме того, вы должны заключить фигурные скобки в кавычки, потому что в определенных последовательностях они могут интерпретироваться как специальные символы регулярного выражения:

 '/{{(.*?)}}/'
  

Экранированная версия символа для определенного разделителя может быть получена с помощью preg_quote функции:

 echo preg_quote('{', '/'); // {
  

Ответ №2:

Вы используете поиск по регулярным выражениям, который требует, чтобы вы объявили шаблон с синтаксисом PCRE.

Ваш шаблон '{{(.*?)}}' имеет { начало и } . PCRE рассматривает их как начало и конец шаблона. Следовательно, они игнорируются из шаблона для сопоставления. Вам нужно заключить шаблон в дополнительные кавычки, чтобы он работал.

Например,

 function handlePattern($matches) {
   echo "matches = " . print_r($matches, true);
}

$article = "{{test1}} {{test2}}";
$article = preg_replace_callback('/{{(.*?)}}/', 'handlePattern', $article);
  

Обратите внимание, что я изменился '{{(.*?)}}' на '/{{(.*?)}}/' .

Результаты:

 matches = Array
(
    [0] => {{test1}}
    [1] => test1
)
matches = Array
(
    [0] => {{test2}}
    [1] => test2
)