Заменить несколько вхождений строки разными значениями - PullRequest
3 голосов
/ 25 сентября 2011

У меня есть скрипт, который генерирует контент, содержащий определенные токены, и мне нужно заменять каждое вхождение токена другим содержимым, полученным в отдельном цикле.

Использовать str_replace просто, чтобы заменить все вхождения токена на одинаковое содержимое, но мне нужно заменить каждое вхождение следующим результатом цикла.

Я видел этот ответ: Поиск и замена нескольких значений несколькими / разными значениями в PHP5?

однако он работает из предопределенных массивов, которых у меня нет.

Пример содержимого:

This is an example of %%token%% that might contain multiple instances of a particular
%%token%%, that need to each be replaced with a different piece of %%token%% generated 
elsewhere.

Мне нужно заменить каждое вхождение %% token %% содержимым, сгенерированным ради аргумента, следующим простым циклом:

for($i=0;$i<3;$i++){
    $token = rand(100,10000);
}

Поэтому замените каждый %% token %% другим значением случайного числа $ token.

Это что-то простое, что я просто не вижу?

Спасибо!

Ответы [ 4 ]

5 голосов
/ 25 сентября 2011

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

Мне кажется, эта проблема хорошо работает с explode(). Итак, на примере предоставленного вами токен-генератора решение выглядит так:

$shrapnel = explode('%%token%%', $str);
$newStr = '';
for ($i = 0; $i < count($shrapnel); ++$i)  {
    // The last piece of the string has no token after it, so we special-case it
    if ($i == count($shrapnel) - 1)
        $newStr .= $shrapnel[$i];
    else
        $newStr .= $shrapnel[$i] . rand(100,10000);
}
1 голос
/ 03 сентября 2013

У меня была похожая проблема, когда у меня был файл, который мне нужно было прочитать. У него было многократное вхождение токена, и мне нужно было заменить каждое вхождение другим значением из массива.

Эта функция заменит каждое вхождение "токена" / "иглы", найденного в "стоге сена", и заменит его значением из индексированного массива.

function mostr_replace($needle, $haystack, $replacementArray, $needle_position = 0, $offset = 0)
{
    $counter = 0;
    while (substr_count($haystack, $needle)) {

        $needle_position = strpos($haystack, $needle, $offset);
        if ($needle_position + strlen($needle) > strlen($haystack)) {
            break;
        }
        $haystack = substr_replace($haystack, $replacementArray[$counter], $needle_position, strlen($needle));
        $offset = $needle_position + strlen($needle);
        $counter++;
    }

    return $haystack;
}

Кстати, «mostr_replace» - это сокращение от «Multiple Occurrence String Replace».

1 голос
/ 12 августа 2013

Я знаю, что это старая тема, но я наткнулся на нее, пытаясь добиться чего-то подобного. Если кто-то еще видит это, я думаю, что это немного лучше:

Создайте образец текста:

$text="This is an example of %%token%% that might contain multiple instances of a particular
%%token%%, that need to each be replaced with a different piece of %%token%% generated 
elsewhere.";

Найдите строку поиска с помощью регулярного выражения:

$new_text = preg_replace_callback("|%%token%%|", "_rand_preg_call", $text);

Определение функции обратного вызова для изменения совпадений

function _rand_preg_call($matches){
  return rand(100,10000);
}

Вывод результатов:

echo $new_text;

Так как функция установлена:

function _preg_replace_rand($text,$pattern){
  return preg_replace_callback("|$pattern|", "_rand_preg_call", $text);
}

function _rand_preg_call($matches){
  return rand(100,10000);
}
0 голосов
/ 23 февраля 2012

Вы можете использовать следующий код:

$content = "This is an example of %%token%% that might contain multiple instances of a particular %%token%%, that need to each be replaced with a different piece of %%token%% generated elsewhere.";

while (true)
{
    $needle = "%%token%%";
    $pos = strpos($content, $needle);
    $token = rand(100, 10000);
    if ($pos === false)
    {
        break;
    }
    else
    {
        $content = substr($content, 0,
                          $pos).$token.substr($content, $pos + strlen($token) + 1);
    }
}
...