【问题标题】:preg_replace throws seg faultpreg_replace 抛出段错误
【发布时间】:2011-05-08 15:34:57
【问题描述】:

当我执行以下代码时;我每次都遇到段错误!这是一个已知的错误?我怎样才能使这段代码工作?

<?php
$doc = file_get_contents("http://prairieprogressive.com/");
$replace = array(
    "/<script([\s\S])*?<\/ ?script>/",
    "/<style([\s\S])*?<\/ ?style>/",
    "/<!--([\s\S])*?-->/",
    "/\r\n/"
);
$doc = preg_replace($replace,"",$doc);
echo $doc;
?>

错误(显然)看起来像:

[root@localhost 2.0]# php test.php
Segmentation fault (core dumped)

【问题讨论】:

  • 你有没有想过使用proper HTML parser
  • 作为注释,我认为您在脚本和样式标签之后缺少&gt;
  • 向我们展示实际的错误。如果您遇到段错误,则可能是您的 PHP 安装存在问题。或者一个错误。无论哪种方式,请遵循 @Gumbo 的建议并使用 HTML 解析器。
  • @Gumbo 这是在页面被 DOMDocument 解析之前清理通常麻烦的标签的预处理的一部分
  • @Cfreak : 我认为这是一个错误,我正在我的笔记本电脑上重现它

标签: php segmentation-fault preg-replace


【解决方案1】:

好的! () 运算符似乎存在一些问题...

当我使用时

$doc = preg_replace("/<style([\s\S]*)<\/ ?style>/",'',$doc);

而不是

$doc = preg_replace("/<style([\s\S])*<\/ ?style>/",'',$doc);

有效!!

【讨论】:

    【解决方案2】:

    试试这个(为 unicode 添加选项 u 并将 ([\s\S])? 更改为 .?:

    <?php
    $doc = file_get_contents("http://prairieprogressive.com/");
    $replace = array(
        "#<script.*?</ ?script>#u",
        '#<style.*?</ ?style>#u',
        "#<!--.*?-->#u",
        "#\r\n#u"
    );
    $doc = preg_replace($replace,"",$doc);
    echo $doc;
    ?>
    

    【讨论】:

      【解决方案3】:

      这似乎是一个错误。

      正如您在评论中提到的那样,是样式正则表达式导致了这种情况。作为一种解决方法,您可以使用 s 修饰符,以便 . 甚至匹配换行符:

      $doc = preg_replace("/<style.*?<\/ ?style>/s",'',$doc);
      

      【讨论】:

        【解决方案4】:

        [\s\S] 的意义何在?它匹配任何空白字符和任何非空白字符。如果你把它换成.*,就可以了。

        编辑:如果您也想匹配新行,请使用 s 修饰符。在我看来,这比矛盾的[\s\S]更容易理解。

        【讨论】:

        • . 默认不匹配 \n[\s\S] 匹配。
        • 那么他可以使用s修饰符。甚至[.\n]*.
        • 是的,他可以,但使用[\s\S] 也是有效的。
        • 使用[\s\S] 代替(.|\n)(但not [.\n])或带有s 修饰符的. 没有任何问题.
        【解决方案5】:

        您有不必要的捕获组,这会影响 PCRE 的回溯。试试这个:

        $replace = array(
            "/<script.*?><\/\s?script>/s",
            "/<style.*?><\/\s?style>/s",
            "/<!--.*?-->/s",
            "/\r\n/s"
        );
        

        另一件事,\s(空白)结合\S(非空白)匹配任何东西。所以只需使用. 模式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-06
          • 2022-11-28
          • 2018-02-24
          • 2019-01-08
          • 1970-01-01
          相关资源
          最近更新 更多