随机替换字符串中的单词

Posted

技术标签:

【中文标题】随机替换字符串中的单词【英文标题】:Replace words in a a string randomly 【发布时间】:2021-05-29 08:36:38 【问题描述】:

我正在尝试编写一个脚本,该脚本将采用文本字符串并允许我替换随机单词。例如:

$str = "The quick brown fox jumps over the lazy dog";

我会像这样替换几个词:

快速的______狐狸跳过____狗

我可以通过首先将字符串拆分为数组来做到这一点

$arr = str_word_count($str, 1);

然后替换$arr[2]$arr[7]

如果字符串中有非单词,我想我会遇到的问题,比如标点符号:

$str = "The quick brown fox, named Jack, jumps over the lazy dog; and Bingo was his...";

我该如何解决这个问题?想法?

【问题讨论】:

您的意思是,例如,“fox”将被替换而不是“fox”? (你的意思是这是问题所在?) 看来您可以在每个子字符串上使用preg_replace。如preg_replace('/[a-zA-Z0-9]+/',... 等。虽然单引号也可以用作标点符号,但缩略词仍然可能是个问题。 @jpf 选择没有标点符号的单词不是问题,str_word_count 已经这样做了。我相信问题是从结果数组中重建句子 - 它会在单词替换过程中丢失所有原始标点符号。不过,preg_replace 在随机选择的单词上是个好主意。 @santa 替换的次数也是随机的吗?字符串可以由多个句子组成还是总是一个句子? 感谢所有建议。实际上,我的意思是用下划线代替,而不是其他词。是的,单词将被随机替换。我可能会添加一个 count() 来检查一个单词中有多少个字母要替换为相同数量的 _(下划线)。是的,主要挑战是用原始标点符号重构句子。 【参考方案1】:

你可以这样做:

   $test1 = "test1";
    $test2 = "test2";
    $test3 = "Bingo2";
    // set new words


    $str = "The quick brown fox, named Jack, jumps over the lazy dog; and Bingo was his...";
    $re = explode(" ", $str);
    // split them on space in array $re
    echo $str  . "<br>";
    $num = 0;

    foreach ($re as $key => $value) 
        echo $value . "<br>";
        $word = "";

        switch (true) 
            case (strpos($value, 'Jack') !== false):
                // cheak if each value in array has in it wanted word to replace 
                // and if it does
                $new = explode("Jack", $value);
                // split at that word just to save punctuation
                $word = $test1 . $new[1];
                //replace the word and add back punctuation
                break;
            case (strpos($value, 'dog') !== false):
                $new1 = explode("dog", $value);
                $word = $test2 . $new1[1];
                break;
            case (strpos($value, 'Bingo') !== false):
                $new2 = explode("Bingo", $value);
                $word = $test3 . $new2[1];
                break;
            default:
                $word = $value;
                // if no word are found to replace just leave it
        

        $re[$num++] = $word;
        //push new words in order back into array
    ;


    echo  implode(" ", $re);
        // join back with space

结果:

The quick brown fox, named test1, jumps over the lazy test2; and Bingo2 was his... 

不管有没有标点符号都可以。

但请记住,如果您有 JackJacky,例如,您将需要添加额外的逻辑,例如使用 Regex to match only letters 检查标点部分是否没有任何字母,如果确实跳过它,这意味着它不是完​​全匹配。或舒缓类似的。

编辑(基于 cmets):

$wordstoraplce = ["Jacky","Jack", "dog", "Bingo","dontreplace"];
$replacewith = "_";
$word = "";
$str = "The quick brown fox, named Jack, jumps over the lazy dog; and Bingo was his...";
echo $str . "<br>";
foreach ($wordstoraplce as $key1 => $value1) 
    $re = explode(" ", $str);
    foreach ($re as $key => $value) 
        if((strpos($value, $value1) !== false))
            $countn=strlen($value1);
            $new = explode($value1, $value);
            if (!ctype_alpha ($new[1]))
                $word = " " . str_repeat($replacewith,$countn) . $new[1]. " ";
            else
                $word = $value;
            
        else
            $word = $value;
        ;
        //echo  $word;  
        $re[$key] = $word;      
    ;
    $str =  implode(" ", $re);
;
echo $str;

结果:

The quick brown fox, named Jack, jumps over the lazy dog; and Bingo was his...
The quick brown fox, named ____, jumps over the lazy ___; and _____ was his... 

【讨论】:

对不起,我在上面的评论中澄清了一点,但这是一个很大的帮助,会让我更进一步。而不是确切的单词,它可能是一个随机键上的字符串,将被替换。 @santa 是的,我现在读了它,这可以很容易地转换为我相信的用例。如果要替换的单词数是 (n),只需为该单词数创建一个循环,然后只使用一个 ifcase,如上所示,逐字逐句进行。 @santa 不确定您所说的“将被替换的随机键”是什么意思,但我的最后一次编辑可以调整。【参考方案2】:

我认为更好的方法是使用正则表达式,因为您不仅允许逗号,还允许所有不是单词字符的内容。正则表达式也比循环中的正常拆分或子字符串快得多。 我的解决方案是:

<?php
function randomlyRemovedWords($str)

    $sentenceParts = [];

    $wordCount = preg_match_all("/([\w']+)([^\w']*)/", $str, $sentenceParts, PREG_SET_ORDER);

    for ($i = 0;$i < $wordCount / 4;$i++)
     //nearly every fourth word will be changed
        $index = rand(0, $wordCount - 1);

        $sentenceParts[$index][1] = preg_replace("/./", "_", $sentenceParts[$index][1]);
    

    $str = "";
    foreach ($sentenceParts as $part)
    
        $str .= $part[1] . $part[2];
    

    return $str;


echo randomlyRemovedWords("The quick brown fox, doesn't jumps over, the lazy dog.");
echo "\n<br>\n";
echo randomlyRemovedWords("The quick brown fox, jumps over, the lazy dog.");

导致

The quick brown ___, _______ jumps over, the ____ dog.
<br>
The quick brown fox, jumps ____, ___ ____ dog.

这样你可以确保忽略所有非单词字符并随机删除单词。

【讨论】:

我喜欢这个!我希望我能接受多个答案。这绝对是一种不同的方法,我喜欢简洁。绝对 +1

以上是关于随机替换字符串中的单词的主要内容,如果未能解决你的问题,请参考以下文章

从数据库中替换句子中的单词(Python / Django)

c#用许多“x”替换字符串[重复]

替换多个字符串中的多个单词

替换字符串中的特定单词(Python)

替换字符串 C++ 位置 X 中的单词

替换字符串中的单词而不跳过空格