简体   繁体   English

PHP替换字符串的随机词

[英]PHP replace a random word of a string

I want to replace one random word of which are several in a string. 我想替换一个随机单词,其中一个字符串中包含多个单词。

So let's say the string is 假设字符串是

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

And let's say I want to replace the word blue with red but only 2 times at random positions. 假设我想用红色替换蓝色一词,但在随机位置仅2次。

So after a function is done the output could be like 所以完成一个功能后,输出可能像

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

Another one could be 另一个可能是

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

So I want to replace the same word multiple times but every time on different positions. 因此,我想多次替换相同的单词,但每次都在不同的位置。

I thought of using preg_match but that doesn't have an option that the position of the words peing replaced is random also. 我想到使用preg_match,但是没有选择peing替换的单词的位置也是随机的。

Does anybody have a clue how to achieve this? 有人知道如何实现这一目标吗?

Much as I am loathed to use regex for something which is on the face of it very simple, in order to guarantee exactly n replaces I think it can help here, as it allows use to easily use array_rand() , which does exactly what you want - pick n random items from a list of indeterminate length ( IMPROVED ). 就像我不喜欢使用regex来处理表面上很简单的事情一样,为了保证正好n个替换,我认为它可以在这里有所帮助,因为它可以轻松使用array_rand() ,它可以完成您的工作想要-从不确定长度的列表中选择n个随机项(已改进 )。

<?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);

See it working 看到它正常工作

echo preg_replace_callback('/blue/', function($match) { return rand(0,100) > 50 ? $match[0] : 'red'; }, $str);

Well, you could use this algorithm: 好吧,您可以使用以下算法:

  1. calculate the random amount of times you want to replace the string 计算您要替换字符串的随机次数
  2. explode the string into an array 将字符串分解为数组
  3. for that array replace the string occurence only if a random value between 1 and 100 is % 3 (for istance) 对于该数组,仅当1到100之间的随机值是%3(用于等距)时,才替换字符串出现
  4. Decrease the number calculated at point 1. 减少在第1点计算的数字。
  5. Repeat until the number reaches 0. 重复直到数字达到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";
?>

NB I just realized this will not replace the first blue, since it is entered into the word array as "blue," and so doesn't match in the array_keys call. 注意,我刚刚意识到这不会替换第一个蓝色,因为它以单词“ blue”输入到单词数组中,因此在array_keys调用中不匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM