Spintax クラスが{spintax|spuntext} のすべてのインスタンスを同じランダムに選択されたオプションに置き換える理由は、クラスの次の行によるものです。
$str = str_replace($match[0], $new_str, $str);
このstr_replace
関数は、部分文字列のすべてのインスタンスを検索文字列の置換で置き換えます。最初のインスタンスのみを置き換えて、必要に応じて順次処理を進めるにはpreg_replace
、渡された "count" 引数を 1 にして関数を使用する必要があります。彼が提案した 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 の提案された置換に関する私の修正を利用して、元のクラスをこの拡張バージョンに置き換えることを検討してください。
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 が提案した文字の正しいエスケープによる置き換えを修正した後\
、無限ループには入りませんでした。
修正された拡張機能を使用して上記のクラスを試し、サーバーで動作するかどうかを確認してください (動作しない理由がわかりません)。