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