需要从给定的句子创建一个随机句子

时间:2014-01-16 07:08:35

标签: php regex function random-sample

以下句子,

{Please|Just} make this {cool|awesome|random} test sentence {rotate {quickly|fast} and random|spin and be random}

我需要创建一个 random()函数,它会给出以下输出: -

Please make this cool test sentence rotate fast and random.
OR
Just make this random test sentence spin and be random.

我不知道我该怎么做。

我在下面尝试但没有得到结果。

echo spinningFunction($str);

function spinningFunction($str)
{
    $output = "";
    $pattern = "/\[.*?\]|\{.*?\}/";
    preg_match_all($pattern, $str, $match);

    $arr = array_map(function($value){
        return explode("|", $value);
    }, $match[1]);


    foreach($arr[0] as $adj)
        foreach($arr[1] as $name)
            $output.= "{$adj} make this {$name} test sentence<br />";
    return $output;
}

有什么帮助吗?

修改: -

function spinningFunction($str)
{
    $str = preg_replace_callback('/(\{[^}]*)([^{]*\})/im', "spinningFunction", $str);
    return $str;
}

有人会帮助我从上面的句子中获得如下所示的数组: -

Array
(
    [0] => Array
        (
            [0] => {Please|Just}
            [1] => {cool|awesome|random}
            [2] => {rotate {quickly|fast} and random|spin and be random}
        )
)

4 个答案:

答案 0 :(得分:2)

这是一个需要对嵌套集使用语法{a|[b|c]}的解决方案。它也只是手动深一层,所以没有干净/简单的递归。根据您的使用情况,这可能会很好。

function randomizeString($string)
{
    if(preg_match_all('/(?<={)[^}]*(?=})/', $string, $matches)) {
        $matches = reset($matches);
        foreach($matches as $i => $match) {
            if(preg_match_all('/(?<=\[)[^\]]*(?=\])/', $match, $sub_matches)) {
                $sub_matches = reset($sub_matches);
                foreach($sub_matches as $sub_match) {
                    $pieces = explode('|', $sub_match);
                    $count = count($pieces);

                    $random_word = $pieces[rand(0, ($count - 1))];
                    $matches[$i] = str_replace('[' . $sub_match . ']',     $random_word, $matches[$i]);
                }
            }

            $pieces = explode('|', $matches[$i]);
            $count = count($pieces);

            $random_word = $pieces[rand(0, ($count - 1))];
            $string = str_replace('{' . $match . '}', $random_word, $string);
        }
    }

    return $string;
}

var_dump(randomizeString('{Please|Just} make this {cool|awesome|random} test sentence {rotate [quickly|fast] and random|spin and be random}.'));
// string(53) "Just make this cool test sentence spin and be random."

var_dump(randomizeString('You can only go two deep. {foo [bar|foo]|abc 123}'));
// string(33) "You can only go two deep. foo foo"

答案 1 :(得分:1)

您必须处理嵌套匹配(请参阅http://php.net/manual/en/regexp.reference.recursive.php中的递归模式)。试试这个

function spinningFunction($str)
{

    $output = "";
    $pattern = "/{(?:[^{}]+|(?R))*}/";
    preg_match_all($pattern, $str, $match);
    print_r($match[0]);

}

$s = "{Please|Just} make this {cool|awesome|random} test sentence {rotate {quickly|fast} and random|spin and be random}";

spinningFunction($s);

模式{(?:[^{}]+|(?R))*}的解释:

{ matches the character { literally

(?:[^{}]+|(?R))* Non-capturing group
 Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]

    1st Alternative: [^{}]+
     [^{}]+ match a single character not present in the list below
     Quantifier: Between one and unlimited times, as many times as possible, giving back as needed [greedy]
     {} a single character in the list {} literally

    2nd Alternative: (?R)
     (?R) recurses the entire pattern

} matches the character } literally

答案 2 :(得分:0)

以下是您要找的内容:

这样的事情:

$text = '{Please|Just} make this {cool|awesome|random} test sentence {rotate|spin) {quickly|fast} and {randomize|spin} the text';

echo 'input-text:<br />'.$text.'<br />';  //echo original string for text output purposes.

$openingConstruct = '{';
$closingConstruct = '}';
$separator = '|';

if(preg_match_all('!'.$openingConstruct.'(.*?)'.$closingConstruct.'!s', $text, $matches)){
  $find = array();
  $replace = array();

  foreach($matches[0] as $key => $match){
    $choices = explode($separator, $matches[1][$key]);
    $find[] = $match;
    $replace[]  = $choices[mt_rand(0, count($choices) - 1)]; 

    foreach($find as $key => $value){
       if(($pos = mb_strpos($text, $value)) !== false) {

       if(!isset($replace[$key])){
          $replace[$key] = '';
       }

       $text = mb_substr($text, 0, $pos).$replace[$key].mb_substr($text, $pos + mb_strlen($value));
    }
    }
}

  echo 'output-text:<br />'.$text;
}

输出:

input-text:
{Please|Just} make this {cool|awesome|random} test sentence {rotate|spin) {quickly|fast} and {randomize|spin} the text

output-text:
Just make this random test sentence rotate and randomize the text

答案 3 :(得分:0)

以下是使用尽可能多的嵌套级别来实现的方法:

function rand_replace($str)
{
    $pattern = "/{([^{}]*)}/";
    while (preg_match_all($pattern, $str, $matches) > 0) {
        for ($i = 0; $i < count($matches[1]); $i++) 
        {
            $options = explode('|', $matches[1][$i]);
            $rand_option = $options[rand(0, count($options)-1)];
            $str = str_replace($matches[0][$i], $rand_option, $str);
        }
    }
    return $str;
}

它首先匹配最深的嵌套替换,随机替换其中一个选项,然后一直工作直到整个字符串被随机化。

使用示例输入从几次运行输出:

Just make this random test sentence rotate fast and random
Please make this random test sentence spin and be random
Please make this cool test sentence rotate fast and random
Just make this random test sentence spin and be random
Please make this awesome test sentence spin and be random
相关问题