0

http://ronaldarichardson.com/2011/09/23/recursive-php-spintax-class-3-0/

このスクリプトは気に入っていますが、完璧ではありません。このテスト入力ケースを使用する場合:

{これは、{spintax|spuntext} 形式の文字列、{spintax|spuntext} 形式の文字列、{spintax|spuntext} 形式の文字列の例です。}

結果には常に「spintax」または「spuntext」のいずれかが 3 回繰り返されていることがわかります。たとえば、1 つの「spintax」と 2 つの「spuntext」が含まれることはありません。

例:

これは、私のスパンテキスト形式の文字列、私のスパンテキスト形式の文字列、私のスパンテキスト形式の文字列の例です。

真にランダムであるためには、各スピンタックス {|} ブロックに対してランダムな反復を生成する必要があり、{spintax|spuntext} のように同一のブロックに対して同じ選択を繰り返さない必要があります。

そのページのコメント #7 を見ると、fransberns は何かに取り組んでいますが、ライブ環境で彼の変更されたコードを使用すると、スクリプトが無限ループで繰り返し実行され、すべてのサーバー メモリが消費されます。そこにバグがあるはずですが、それが何であるかはわかりません。

何か案は?または、ネストされたスピンタックスを可能にし、真にランダムな堅牢な PHP スピンタックス スクリプトを知っている人はいますか?

4

2 に答える 2

1

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 が提案した文字の正しいエスケープによる置き換えを修正した後\、無限ループには入りませんでした。

修正された拡張機能を使用して上記のクラスを試し、サーバーで動作するかどうかを確認してください (動作しない理由がわかりません)。

于 2012-08-07T14:38:30.280 に答える