0

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 并且是真正随机的?

4

2 回答 2

1

请检查这个要点,它正在工作(它比原始代码简单得多..)。

于 2012-08-07T14:16:49.020 回答
1

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 的建议替换为正确转义\字符后,我没有进入无限循环。

使用更正的增强尝试上面的类,看看它是否适用于您的服务器(我看不出它不应该的原因)。

于 2012-08-07T14:38:30.280 回答