http://ronaldarichardson.com/2011/09/23/recursive-php-spintax-class-3-0/
我喜欢这个剧本,但它并不完美。如果您使用此测试输入案例:
{这是我的{spintax | spuntext}格式化字符串,我的{spintax | spuntext}格式化字符串,我的{spintax | spuntext}格式化字符串示例。}
你可以看到结果总是包含3次重复的" spintax"或" spuntext"。它永远不会包含1" spintax"和2" spuntext",例如。
示例:
这是我的spuntext格式化字符串,我的spuntext格式化字符串,我的spuntext格式化字符串示例。
要真正随机,它需要为每个spintax {|}块生成一个随机迭代,而不是对相同的块重复相同的选择,如{spintax | spuntext}。
如果您查看该页面上的注释#7,那么fransberns就会出现问题,但是当在实时环境中使用他修改过的代码时,该脚本会在无限循环中重复运行并占用所有服务器内存。所以那里肯定有一个错误,但我不确定它是什么。
有什么想法吗?或者有没有人知道一个强大的PHP spintax脚本允许嵌套的spintax并且是真正的随机?
答案 0 :(得分:1)
请检查此gist,它正常工作(它比原始代码简单得多..)。
答案 1 :(得分:1)
Spintax类用相同的随机选择的选项替换{spintax | spuntext}的所有实例的原因是因为该类中的这一行:
$str = str_replace($match[0], $new_str, $str);
str_replace
函数用搜索字符串中的替换替换子字符串的所有实例。要替换仅第一个实例,按照需要以串行方式进行,我们需要使用函数preg_replace
并将传递的“count”参数设置为1.但是,当我查看时your link到Spintax类并引用#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'建议替换后,我没有进入\
字符的正确转义。
使用更正的扩充程序尝试上面的类,看看它是否适用于您的服务器(我看不出它不应该出现的原因)。