简体   繁体   中英

replace a random word of a string with a random replacement

I am developing a script that takes an article, searches the article for a "keyword" and then randomly replaces that keyword with an anchor link.

I have the script working as it should, however I need to be able to have an array of "replacements" for the function to loop through and insert at the random location.

So the first random position would get anchor link #1. The second random position would get anchor link #2. The third random position would get anchor link #3. etc...

I found half of the answer to my question here: PHP replace a random word of a string

public function replace_random ($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;

}

So my question is, How can i alter this function to accept an array for the $replace variable?

EDIT I have also attempted to get random array keys from mt_rand, which outputs my replacement from an array of replacements, but it is still only adding one of the replacements throughout the content. I would like the function to pick one "keyword" for each instance of the $search variable that it found.

public function replace_random ($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;

    $searchCount = count($replace);
    $arrayNum = mt_rand(0, 4);

    // 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[$arrayNum].substr($str, $matches[0][$match][1] + $searchLen + $offset);
        $offset += $diff;
    }

    return $str;

}

the solution turned out that i needed to add a variable to the foreach loop:

$replaceRand    =   $replace[array_rand($replace)];

and call it in the $str variable:

$str = substr($str, 0, $matches[0][$match][1] + $offset).$replaceRand.substr($str, $matches[0][$match][1] + $searchLen + $offset);

the whole code ended up being:

public function replace_random ($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) {
        $replaceRand    =   $replace[array_rand($replace)];
        $str = substr($str, 0, $matches[0][$match][1] + $offset).$replaceRand.substr($str, $matches[0][$match][1] + $searchLen + $offset);
        $offset += $diff;
    }

    return $str;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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