Spintax 类用随机选择的相同选项替换 {spintax|spuntext} 的 所有 个实例的原因是因为类中的这一行:
$str = str_replace($match[0], $new_str, $str);
str_replace 函数将子字符串的 all 实例替换为搜索字符串中的替换。要仅替换第一个实例,按照您的需要以串行方式进行,我们需要使用函数preg_replace,传递的“count”参数为1。但是,当我查看@987654321 @ 到 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' 建议替换为\ 字符的正确转义后,我没有进入无限循环。
用更正的增强试试上面的类,看看它是否在你的服务器上工作(我看不出它不应该的原因)。