PHP:如何在随机替换术语的同时遍历字符串?

时间:2014-03-14 10:41:22

标签: php arrays random

我有一个字符串,是这样的一段文字:

$input = AAAA BBBB CCCC DDD E FFFF GGG AAAA HHHH IIII JJJ KKKK

我也有这样的数组:

$terms[0][0] = "AAAA";
$terms[0][1] = "KKKK";
$terms[0][2] = "A2A2";
$terms[1][0] = "FFFF";
$terms[1][1] = "TTT";
$terms[1][2] = "FFF1";

这些价​​值观不是真实的,也不重要。该数组由同义词组成。这意味着所有$terms[0]键具有相同的含义。我的全部观点是用同一个$string键中的同义词随机替换$term中的匹配项,例如:

$output == KKKK BBBB CCCC DDD E FF1F GGG A2A2 HHH III JJJ AAAA

$output == A2A2 BBBB CCCC DDD E TTT GGG KKKK HHH III JJJ AAAA

$output == A2A2 BBBB CCCC DDD E FFF1 GGG KKKK HHH III JJJ A2A2

我该怎么做?

我设法做的就是循环使用$ terms [] []并使用相同的上一个键中的随机值为每个匹配构建一个replace_pairs数组,之后再使用strtr()这样:

$replace_pairs[AAAA] = "KKKK";
$replace_pairs[FFFF] = "TTT";
$replace_pairs[KKKK] = "A2A2";
$output = strtr($input, $replace_pairs);

但是,这会将所有相等匹配(在此示例中为AAAA到KKKK)替换为相同的值,如下所示:

$output == KKKK BBBB CCCC DDD E TTTF GGG KKKK HHH III JJJ A2A2

有什么方法可以在"走过"字符串,所以我总是可以从同义词的数组中获取一个新的随机元素?请记住,同义词也有不同的长度。

2 个答案:

答案 0 :(得分:0)

试试这个:

$input = "AAAA BBBB CCCC DDD E FFFF GGG AAAA HHHH IIII JJJ KKKK";
$terms[0][0] = "AAAA";
$terms[0][1] = "KKKK";
$terms[0][2] = "A2A2";
$terms[1][0] = "FFFF";
$terms[1][1] = "TTT";
$terms[1][2] = "FFF1";

$inputarr = explode(" ", $input);
$outputarr = array();
foreach($inputarr as $num => $element){
    $outputarr[$num] = $element;
    foreach($terms as $keys){
        if (in_array($element, $keys)){
            $outputarr[$num] = $keys[rand(0,(count($keys) - 1))];
            break 1;
        }
    }
}
$output = implode(" ", $outputarr);

答案 1 :(得分:0)

您可以使用array_*和lambda函数高效地执行此操作:

<?php

// This is the same format of your $terms array.    
$synonyms   = array(
    array(
        'have','possess'
    ),
    array(
        'nice','good','wonderful','pleasurable',
    ),
    array(
        'day','tide','period',
    )
);

$input = "have a nice day.\n";

function synonymize($input, $synonyms) {

    // Replace each word (word-boundary word-characters word-boundary)
    return preg_replace_callback('#\\b(\\w+)\\b#', function($matches) 
        use ($synonyms) {

        $word   = $matches[1];

        // Find what synonyms, if any, this word has.
        $poss   = array_filter($synonyms, function($candidates) use ($word) {
            return in_array($word, $candidates);
        });

        // If none, we can't replace.
        if (empty($poss)) {
            return $word;
        }

        $among  = array_pop($poss);

        // Otherwise return the alternative.

        $newword = $among[rand(0, count($among)-1)];
        // log("replacing {$word} with {$newword}");
        return $newword;

    },
    $input);
}

for ($i = 0; $i < 8; $i++) { print synonymize($input, $synonyms); }
?>

收率:

have a pleasurable day.
have a nice day.              // Note: null substitution.
possess a wonderful tide.
possess a wonderful period.
possess a good period.
possess a nice tide.
have a nice period.           // Note: poor choice of synonyms.
have a pleasurable day.       // Note: repetition (of course).