2012-08-03 93 views
0

http://ronaldarichardson.com/2011/09/23/recursive-php-spintax-class-3-0/为什么这个PHP spintax代码重复相同的迭代?

我喜欢这个脚本,但它并不完美。如果您使用此测试输入案例:{这是我的{spintax | spuntext}格式化字符串,我{spintax | spuntext}格式化字符串,我{spintax | spuntext}格式的字符串,例如}

你可以看到结果总是包含3次重复的“spintax”或“spuntext”。例如,它从不包含1个“spintax”和2个“spuntext”。

实施例:

这是我spuntext格式的字符串,我的spuntext格式的字符串,我的spuntext格式的字符串的例子。

要真正随机,它需要为每个spintax {|}块生成一个随机迭代,而不是为相同的块重复相同的选择,如{spintax | spuntext}。

如果您查看该页面上的评论#7,fransberns就是一些东西,但是在实时环境中使用他的修改后的代码时,脚本会反复运行在一个无限循环中,并吞噬所有服务器内存。所以那里肯定有bug,但我不确定它是什么。

任何想法?还是有人知道一个强大的PHP spintax脚本允许嵌套spintax,并且是真正的随机?

+0

附注:你真的想要它是随机的吗?或者你正在寻找不同的输出?如果它是随机的,完全有可能有许多重复的单词。 – HappyTimeGopher 2012-08-03 22:27:13

+0

我现在还没有机会写+测试它,但是您需要对preg_replace应用一个限制,并在目标单词仍在文档中时循环。添加一个计数器并打破之后,说20个循环以避免无限循环。 – HappyTimeGopher 2012-08-03 22:31:19

+0

@HappyTimeGopher - 是的,随机的。我很好,在上面的情况下,“spintax”重复3次,一次又一次,而不是每次运行该函数的时间;) – Kane 2012-08-03 22:36:34

回答

1

请检查这个gist,它工作(而且它比原来的代码简单得多..)。

+0

这是我最终选择的解决方案,因为它比我正在使用的原始代码。 – Kane 2012-08-08 21:43:29

1

原因的Spintax类取代的所有实例{spintax | spuntext}具有相同的随机选择的选项是因为该线在类的:

$str = str_replace($match[0], $new_str, $str); 

str_replace函数替换所有实例在搜索字符串中替换的子字符串。要取代只有第一个实例,按照您所希望的顺序进行,我们需要使用函数preg_replace,并且传递的“count”参数为1.但是,当我查看Spintax类的your link并引用post #7我注意到他对Spintax课程的建议增强有一个错误。

fransberns建议更换:

$str = str_replace($match[0], $new_str, $str); 

与此:

//one match at a time 
$match_0 = str_replace("|", "\|", $match[0]); 
$match_0 = str_replace("{", "\{", $match_0); 
$match_0 = str_replace("}", "\}", $match_0); 
$reg_exp = "/".$match_0."/"; 
$str = preg_replace($reg_exp, $new_str, $str, 1); 

fransbergs'建议的问题是,在他的代码,他没有正确构建的正则表达式的preg_replace功能。他的错误来自于没有正确逃脱\角色。接替他的代码应该是这个样子的:

//one match at a time 
$match_0 = str_replace("|", "\\|", $match[0]); 
$match_0 = str_replace("{", "\\{", $match_0); 
$match_0 = str_replace("}", "\\}", $match_0); 
$reg_exp = "/".$match_0."/"; 
$str = preg_replace($reg_exp, $new_str, $str, 1); 

考虑利用我校在fransberns'建议replacemnet:

class Spintax { 

    function spin($str, $test=false) 
    { 
     if(!$test){ 
     do { 
      $str = $this->regex($str); 
     } while ($this->complete($str)); 
     return $str; 
     } else { 
     do { 
      echo "<b>PROCESS: </b>";var_dump($str = $this->regex($str));echo "<br><br>"; 
     } while ($this->complete($str)); 
     return false; 
     } 
    } 

    function regex($str) 
    { 
     preg_match("/{[^{}]+?}/", $str, $match); 
     // Now spin the first captured string 
     $attack = explode("|", $match[0]); 
     $new_str = preg_replace("/[{}]/", "", $attack[rand(0,(count($attack)-1))]); 
//  $str = str_replace($match[0], $new_str, $str); //this line was replaced 
     $match_0 = str_replace("|", "\\|", $match[0]); 
     $match_0 = str_replace("{", "\\{", $match_0); 
     $match_0 = str_replace("}", "\\}", $match_0); 
     $reg_exp = "/".$match_0."/"; 
     $str = preg_replace($reg_exp, $new_str, $str, 1);  
     return $str; 
    } 

    function complete($str) 
    { 
     $complete = preg_match("/{[^{}]+?}/", $str, $match); 
     return $complete; 
    } 
} 

当我试图用fransberns'这个增强版本替换原始类建议替换为“原样”,由于\字符不正确的转义,我得到了一个无限循环。我认为这是你的记忆问题来自的地方。在纠正fransberns'建议的替换与\字符的正确转义我没有进入无限循环。

尝试使用更正的扩充以上的类,看看它是否在你的服务器上工作(我看不出它不应该这样做的原因)。