1

我想替换一个字符串中的一个随机单词。

所以假设字符串是

$str = 'I like blue, blue is my favorite colour because blue is very nice and blue is pretty';

假设我想用红色替换蓝色这个词,但在随机位置只替换 2 次。

所以在一个功能完成后,输出可能就像

I like red, blue is my favorite colour because red is very nice and blue is pretty

另一个可能是

I like blue, red is my favorite colour because blue is very nice and red is pretty

所以我想多次替换同一个词,但每次都在不同的位置。

我想过使用 preg_match ,但是没有选项 peing 替换的单词的位置也是随机的。

有人知道如何实现这一目标吗?

4

4 回答 4

3

尽管我很讨厌将正则表达式用于表面上非常简单的事情,但为了保证准确地替换n,我认为它在这里可以提供帮助,因为它允许使用轻松使用array_rand(),这正是你想要的 - 选择来自不确定长度列表的n 个随机项目 ( IMPROVED )。

<?php

    function replace_n_occurences ($str, $search, $replace, $n) {

        // Get all occurences of $search and their offsets within the string
        $count = preg_match_all('/\b'.preg_quote($search, '/').'\b/', $str, $matches, PREG_OFFSET_CAPTURE);

        // Get string length information so we can account for replacement strings that are of a different length to the search string
        $searchLen = strlen($search);
        $diff = strlen($replace) - $searchLen;
        $offset = 0;

        // Loop $n random matches and replace them, if $n < 1 || $n > $count, replace all matches
        $toReplace = ($n < 1 || $n > $count) ? array_keys($matches[0]) : (array) array_rand($matches[0], $n);
        foreach ($toReplace as $match) {
            $str = substr($str, 0, $matches[0][$match][1] + $offset).$replace.substr($str, $matches[0][$match][1] + $searchLen + $offset);
            $offset += $diff;
        }

        return $str;

    }

    $str = 'I like blue, blue is my favorite colour because blue is very nice and blue is pretty';

    $search = 'blue';
    $replace = 'red';
    $replaceCount = 2;

    echo replace_n_occurences($str, $search, $replace, $replaceCount);

看到它工作

于 2012-05-22T15:24:54.620 回答
2
echo preg_replace_callback('/blue/', function($match) { return rand(0,100) > 50 ? $match[0] : 'red'; }, $str);
于 2012-05-22T15:02:28.877 回答
1

好吧,你可以使用这个算法:

  1. 计算要替换字符串的随机次数
  2. 将字符串分解为数组
  3. 对于该数组,仅当 1 到 100 之间的随机值是 % 3 时才替换字符串出现(例如)
  4. 减少在点 1 处计算的数字。
  5. 重复直到数字达到 0。
于 2012-05-22T14:55:18.767 回答
0
<?php
$amount_to_replace = 2;
$word_to_replace = 'blue';
$new_word = 'red';

$str = 'I like blue, blue is my favorite colour because blue is very nice and blue is pretty';

$words = explode(' ', $str); //convert string to array of words
$blue_keys = array_keys($words, $word_to_replace); //get index of all $word_to_replace

if(count($blue_keys) <= $amount_to_replace) { //if there are less to replace, we don't need to randomly choose.  just replace them all
    $keys_to_replace = array_keys($blue_keys);
}
else {
    $keys_to_replace = array();
    while(count($keys_to_replace) < $amount_to_replace) { //while we have more to choose
        $replacement_key = rand(0, count($blue_keys) -1);
        if(in_array($replacement_key, $keys_to_replace)) continue; //we have already chosen to replace this word, don't add it again
        else {
            $keys_to_replace[] = $replacement_key;
        }
    }
}

foreach($keys_to_replace as $replacement_key) {
    $words[$blue_keys[$replacement_key]] = $new_word;
}

$new_str = implode(' ', $words); //convert array of words back into string
echo $new_str."\n";
?>

注意我刚刚意识到这不会替换第一个蓝色,因为它作为“蓝色”输入到单词数组中,因此在 array_keys 调用中不匹配。

于 2012-05-22T15:03:43.047 回答