Как преобразовать preg_replace с шаблоном в массиве в preg_replace_callback?

Я пытаюсь перенести свои сайты с PHP 5,4 до HHVM. я узнал, что preg_replace / e был E_DEPRECATED, поэтому я попытался преобразовать все вхождения как можно. Я исправил много частей, но не смог преобразовать те шаблон в массиве. Ниже приведен один из случаев:

if(strpos($msglower, '[/img]') !== FALSE) {
$message = preg_replace(array(
"/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/ies",
"/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/ies"), $allowimgcode ? array(
"bbcodeurl('\\1', '<img src=\"%s\" border=\"0\" onclick=\"zoom(this, this.src)\" onload=\"attachimg(this, \'load\')\" alt=\"\" />')",
"bbcodeurl('\\3', '<img width=\"\\1\" height=\"\\2\" src=\"%s\" border=\"0\" alt=\"\" />')") : array(
"bbcodeurl('\\1', '<a href=\"%s\" target=\"_blank\">%s</a>')",
"bbcodeurl('\\3', '<a href=\"%s\" target=\"_blank\">%s</a>')"), $message);
}

Я знал, что я должен использовать анонимную функцию для преобразования, но я не уверен, где function($matchese){return XXXXXXXXXXXX;} должны быть размещены, так как их более одного preg_replace /e в массиве шаблонов. Я попытался поместить в начало строки ЗАМЕНА или перед каждым элементом массива. Оба терпят неудачу. Я застрял в этом в течение двух дней. Кто-нибудь может помочь мне решить это?

Я попытался изменить, как вы предложили, добавив анонимные функциональные блоки в каждом возвращаемом массиве, но это даст мне пустой контент в этой позиции:

if(strpos($msglower, '[/img]') !== FALSE) {
$message = preg_replace_callback(array(
"/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
"/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is"), $allowimgcode ? function($v) {return array(
"bbcodeurl('$v[1]', '<img src=\"%s\" border=\"0\" onclick=\"zoom(this, this.src)\" onload=\"attachimg(this, \'load\')\" alt=\"\" />')",
"bbcodeurl('$v[3]', '<img width=\"$v[1]\" height=\"$v[2]\" src=\"%s\" border=\"0\" alt=\"\" />')");} : function($v) {return array(
"bbcodeurl('$v[1]', '<a href=\"%s\" target=\"_blank\">%s</a>')",
"bbcodeurl('$v[3]', '<a href=\"%s\" target=\"_blank\">%s</a>')");}, $message);
}

Это одна из моих предыдущих попыток. Кажется, это не работает.

В соответствии с напоминанием Axiac, что заменяющая часть должна быть строкой и не может быть массивом, я попробовал это и, кажется, работает:

if(strpos($msglower, '[/img]') !== FALSE) {
$message = preg_replace_callback("/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
$allowimgcode ? function($v) {return bbcodeurl($v[1], '<img src="%s" border="0" onclick="zoom(this, this.src)" onload="attachimg(this, \'load\')" alt="" />');} :
function($v) {return bbcodeurl($v[1], '<a href="%s" target="_blank">%s</a>');}, $message);
$message = preg_replace_callback("/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
$allowimgcode ? function($v) {return bbcodeurl($v[3], "<img width=\"$v[1]\" height=\"$v[2]\" src=\"%s\" border=\"0\" alt=\"\" />");} :
function($v) {return bbcodeurl($v[3], '<a href="%s" target="_blank">%s</a>');}, $message);
}

Большое спасибо, ребята!

1

Решение

призвание preg_replace_callback() с массивом строк поиска возможно только при наличии единственной замены для них (когда параметр $replacement вызова preg_replace() Вы хотите заменить это строка, а не массив). Это связано с тем, что параметр, предоставленный для обратного вызова, не содержит никакой информации о том, какая из строк поиска создала совпадение, для которого вызывается обратный вызов.

Поскольку ваши замены зависят от строки поиска, я предлагаю вам выполнять каждую замену, используя новый вызов preg_replace_callback(), Таким образом, вам нужно написать отдельные функции для каждого набора строк поиска / замены.

Функция обратного вызова получает в качестве параметра массив совпадений (тот же массив, который заполнен preg_match() когда получен в качестве третьего аргумента). Использовать use языковая конструкция (как объяснено в третьем примере на странице документации о anonymous functions сообщить обратному вызову о значении переменной $allowimgcode:

$message = preg_replace_callback(
"/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
function (array $matches) use ($allowimgcode) {
if ($allowimgmode) {
return bbcode($matches[1], '<img src="%s" border="0" onclick="zoom(this, this.src)" onload="attachimg(this, \'load\')" alt="" />');
} else {
return bbcode($matches[1], '<a href="%s" target="_blank">%s</a>');
}
}
$message,
);

Если имеется много пар поиска / замены, вы можете организовать поиск вместе с функциями замены в список (и использовать отдельные обратные вызовы для каждого сценария). Код чище таким образом:

// The search strings and their alternate replacements
$replacements = array(
array(
// The search regex
'search' => "/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
// The callback when $allowimgcode is TRUE
'images' => function (array $matches) {
return bbcode($matches[1], '<img src="%s" border="0" onclick="zoom(this, this.src)" onload="attachimg(this, \'load\')" alt="" />');
},
// The callback when $allowimgcode is FALSE
'noimgs' => function (array $matches) {
return bbcode($matches[1], '<a href="%s" target="_blank">%s</a>');
},
),
array(
'search' => "/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
'images' => function (array $matches) {
return bbcode($matches[3], '<img width="'.$matches[1].'" height="'.$matches[2].'" src="%s" border="0" alt="" />');
},
'noimgs' => function (array $matches) {
return bbcode($matches[3], '<a href="%s" target="_blank">%s</a>');
},
),
);

Затем выполните замены одну за другой в цикле:

foreach ($replacements as $set) {
$message = preg_replace_callback(
$set['search'],
// select the correct replacement callback depending on $allowimgcode
$allowimgcode ? $set['images'] : $set['noimgs'],
$message
);
}
1

Другие решения

Один и тот же обратный вызов используется для каждого совпадения, поэтому вы можете предоставить только один обратный вызов, как это —

if(strpos($msglower, '[/img]') !== FALSE) {
$message = preg_replace_callback(array(
"/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
"/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is"), $allowimgcode ? function ($matchese) {return "XXXX";} :
function($matchese) { return "XXXXX";}
, $message);
}

(Я оставлю это вам, чтобы конкретизировать функции замены)

Вы можете проверить соответствие, которое вы получите, чтобы выяснить, какое из двух совпадений у вас есть (или вы можете разделить его на два отдельных вызова preg_replace_callback). Ответ на этот вопрос имеет несколько идей о том, как сделать так, чтобы вам было легче выяснить, какое совпадение у вас есть — preg_replace_callback с шаблоном массива и заменой

0

Привет, Дэвид и Дж. Сьюис Чарли,

Я попытался изменить, как вы предложили, добавив анонимные функциональные блоки в каждом возвращаемом массиве, но это даст мне пустой контент в этой позиции:

if(strpos($msglower, '[/img]') !== FALSE) {
$message = preg_replace_callback(array(
"/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is",
"/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is"), $allowimgcode ? function($v) {return array(
"bbcodeurl('$v[1]', '<img src=\"%s\" border=\"0\" onclick=\"zoom(this, this.src)\" onload=\"attachimg(this, \'load\')\" alt=\"\" />')",
"bbcodeurl('$v[3]', '<img width=\"$v[1]\" height=\"$v[2]\" src=\"%s\" border=\"0\" alt=\"\" />')");} : function($v) {return array(
"bbcodeurl('$v[1]', '<a href=\"%s\" target=\"_blank\">%s</a>')",
"bbcodeurl('$v[3]', '<a href=\"%s\" target=\"_blank\">%s</a>')");}, $message);
}

Это одна из моих предыдущих попыток. Кажется, это не работает.

0
По вопросам рекламы [email protected]