скажем, у меня есть эта строка:
"my string ? other string ?"
"first param ?" (обратите внимание на заполнитель ? внутри текста)"second param".ЕСЛИ я делаю preg_replace, я получаю это:
my string first param second param other string ?
^^^^^^^^^^^^^^^^^^^^^^^^ ^
WRONG NOT REPLACED
По сути, поскольку первая замена также имеет заполнитель, preg_replace достаточно глупо заменить этот заполнитель вместо реального второго в конце.
Код с preg_replace:
$search = ["?", "?"];
$params = ["first param ?", "second param"];
$query = "first text ? other text ?";
//> Marker in the query are ?, so I create the array to preg_replace
$search = array_fill(0,count($params),'/\?/');
$query = preg_replace(
$search, // a list of ?
$params, // escaped values
$query, // from query
1 // replace only 1 time
);
//output: first text first param second param other text ?
Любой намек на то, как избежать поиска заполнителя внутри замены?
Живой код с preg_replace: http://sandbox.onlinephpfunctions.com/code/e705ba454d030103344bc826e0fe0bf42d5b7b90
Не работает также с str_replace
$search = ["?", "?"];
$params = ["first param ?", "second param"];
$query = "first text ? other text ?";
$query = str_replace ($search, $params, $query);
echo $query;
// output: first text first param second param other text first param second param
Живой код с str_replace: http://sandbox.onlinephpfunctions.com/code/dc259325411ee42de759f145eac78b339f329f74
Дано:
$search = ["?", "?"];
$params = ["first param ?", "second param"];
$query = "first text ? other text ?";
Ожидаемый результат:
first text first param ? other text second param
^^^^^^^^^^^^^ ^^^^^^^^^^^^
first placeholder second placeholder
$search = ["?", "?", "?"];
$params = ["first param", "second param ?", "third param"];
$query = "first text ? other text ? other chunk ?";
Ожидаемый результат:
first text first param other text second param ? other chunk third param
^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^
first placeholder second placeholder third placeholder
Я придумал возможное решение, используя preg_split, но, честно говоря, это настолько хакерски, что должно быть что-то лучше:
$parts = preg_split('/(\?)/', $query, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach($parts as $k=>&$v) {
// if is odd, then it's a placeholder
if ($k%2 == 1)
$v = $params[$k/2]; // replace placeholder with a param
}
$query = implode('',$parts);
попробовал, не работает, потому что он заменяет оба заполнителя два раза, я добавил тест живого кода в свой исходный пост
вы хотите использовать str_replace()? см. демо для этого 3v4l.org/t4QKq
Пробовал с str_replace, и это не работает, потому что несколько раз заменяет один и тот же заполнитель: sandbox.onlinephpfunctions.com/code/…
каков ваш ожидаемый результат в данном примере с песочницей?
@AlwaysSunny: я добавил ожидаемый результат в конце своего поста
извините за вопрос, но вы пытаетесь создать что-то для mySql
Тито: нет, похоже, но не sql
Ко всем: пока мы разговаривали, я добавил свое возможное решение (найдите его ниже), оно использует preg_split, но, честно говоря, это что-то очень плохое






$search = [
"/^([^?]*)\?/", # matches everything that is not a question mark in group 1, then a question mark
"/^(.*)\?/" # matches everything until last question mark in group 1, then a question mark
];
$params = ["$1first param ?", "$1second param"];
$query = "first text ? other text ?";
$query = preg_replace($search, $params, $query);
echo $query;
Выход:
first text first param ? other text second param
Тото +1, но этот материал динамический, я не знаю, сколько $search прибудет в эту функцию. Он должен быть общим
@giò: Не могли бы вы привести примеры и ожидаемый результат для 3 или более заполнителей? с участием
Пытаться:
$s = "my string ? other string ?";
$s = preg_replace('/\?/', "first ?", $s, 1);
$s = preg_replace('/((?:^.*?\?)?.*?)\?/', "$1second text", $s);
echo $s;
Базируется в Как пропустить первое совпадение с регулярным выражением?
Любая пользовательская логика замены должна быть реализована с помощью preg_replace_callback, например:
$params = ["first param", "second param ?", "third param"];
$query = "first text ? other text ? other chunk ?";
echo preg_replace_callback('/\?/', function($m) use (&$params) {
return array_shift($params);
}, $query);
Текущий код: http://sandbox.onlinephpfunctions.com/code/33f4804b49103e54e8070e8d9959ec9642930857
Хорошо, позвольте мне создать живой фрагмент, готово. Очень приятно, хотя это не «пользовательская» логика replacemnet, это просто очень простая последовательная замена заполнителя :)
Я только что обновил свой ответ тем же. Вы поняли мою точку зрения.
Это можно сделать с помощью цикла while() с проверкой strpos(), но также explode() является еще одним решением этой проблемы:
$params = ['first param ?', 'second param'];
$query = 'my string ? other string ?';
$str = '';
foreach(explode('?', $query, count($params) + 1) as $token) {
$str .= $token . array_shift($params);
}
echo $str;
да +1, взрыв похож на preg_slit, альт, посмотрев фрагмент, я думаю, что принятый ответ - самое простое решение
Да, но разница в том, что в explode() нет слоя PCRE, как это происходит в preg_split() или других preg_* функциях. Поэтому он должен работать быстрее.
Что если убрать ограничение
, 1?