【问题标题】:Why does preg_match_all break with this regex?为什么 preg_match_all 会与这个正则表达式中断?
【发布时间】:2018-07-01 08:08:48
【问题描述】:

我今天大部分时间都在与一个神秘的崩溃作斗争,我终于解决了,但我并不真正理解我自己的解决方法。

代码的目的是替换模板中的占位符。

以下是重现问题所需的最终最低 PHP 代码。

$path = realpath("path_to_template.html");
$content = file_get_contents($path);
$loop_regex = '/{{\*(\w+)}}((?:.|\n)+?){{\/\w+}}/s';
$data = array(
    "Trainees"=> array(
        array(
             "display_name" => "Joe",
             "status" => "Pending",
             "invited_date" => "01 Sep 2018",
             "percentage" => "80%"
       )
    )
);

preg_match_all($loop_regex, $content, $output_array);

模板:

<table>
    <tbody>
    <tr>
        <th>Trainee</th>
        <th>Status</th>
        <th>Invited</th>
        <th>Score</th>
        <th>Action</th>
    </tr>
    {{*Trainees}}
    <tr>
        <td>{{display_name}}</td>
        <td>{{status}}</td>
        <td>{{invited_date}}</td>
        <td>{{percentage}}</td>
        <td>Some action button</td>
    </tr>
    {{/Trainees}}
    </tbody>
</table>

在我尝试向模板中添加更多内容之前,一切都很好。突然之间,ERR_CONNECTION_RESET 每当它到达 preg_match_all 时。

断点似乎仅与 {{Trainees}} 组内的内容大小有关,当它达到大约 395 个字符时,它就断了。

我通过 Drupal 博客发现将它添加到 Apache httpd.config 可以修复它。

<IfModule mpm_winnt_module>
   ThreadStackSize 8388608
</IfModule>

但我真的不明白为什么这段代码会超过堆栈大小,因此我可能仍然可以轻松地用更多内容打破它。

欢迎任何理论。

环境: WAMPServer 3.0.8、PHP 5.6.25、Apache 2.4.23

【问题讨论】:

  • 您尝试正则表达式的文件有多大?
  • 为什么不使用像 Twig 这样的模板引擎?
  • 文件超小,1kb
  • 是的,谢谢亚历克斯。我可能应该使用 Twig 或类似工具,但这是在我的第一个定制 Wordpress 构建中,坦率地说,我还不想为一个相当简单的实现添加另一个移动部分。

标签: php regex apache preg-match-all pcre


【解决方案1】:

表达式

{{\*(\w+)}}((?:.|\n)+?){{\/\w+}}

效果很差,更好用

{{\*(\w+)}}(.+?){{/\w+}}

与其他分隔符,例如~ 代替。


您的旧表达式需要 780 步(参见 this demo on regex101.com),而后者只需要 404 步(参见 another demo here)。

【讨论】:

  • 公平竞争一月!那个正则表达式效果更好,我也添加了额外的内容并且它支持。另外,我不知道“步骤”的东西,所以你也教了我一些别的东西。
  • @RossCoombes:与匹配一样重要的通常是实现此目标所需的步骤数量。无论如何,很高兴能提供帮助。
【解决方案2】:

顺便说一句,我还发现切换到 PHP 7.0.10 也可以解决这个问题,但这可能会掩盖我原来的正则表达式的低效率,所以 Jan 的答案似乎是正确的。

【讨论】:

    猜你喜欢
    • 2019-09-10
    • 2010-09-22
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多