【问题标题】:preg_replace vs DOMDocument replaceChildpreg_replace vs DOMDocument replaceChild
【发布时间】:2014-05-23 16:46:59
【问题描述】:

我想知道标题中提到的哪种方法可以更有效地替换 html 页面中的内容。

我的页面中有这个自定义标签:<includes module='footer'/>,它将被一些内容替换。

现在使用DOMDocument->getElementsByTagName('includes')->item(0)->parentNode->replaceChild 有一些缺点,例如当我忘记在标签中添加斜线时,就像<includes module='footer'> 整个网站崩溃。

正则表达式允许这样的例外,只要它符合规则。它甚至可以让我替换任何字符串,比如{includes:footer}

现在回到我的实际问题。为此目的使用正则表达式是否有任何缺点,例如性能问题...?

更多:Append child/element in head using XML Manipulation

干杯

【问题讨论】:

    标签: php regex preg-replace domdocument appendchild


    【解决方案1】:

    我不会太担心这里的性能,我会认为它们“可比”。需要运行基准测试才能真正确定这一点,因为这取决于文档的大小以及正则表达式的编写方式。

    相反,我会担心准确性。一般来说,DOMDocument 在解析 XML 方面会更好,因为它是为阅读和理解语言而构建的。但是,它在<includes module='footer'> 上确实失败了,因为它是一个未关闭的标签(预期:</includes>)。

    最常见的 HTML/XML 格式问题可以通过 PHP 的 Tidy 类修复。我会检查一下,因为您应该收到更多 "expected results" compared to if you used regex 来解析。如果您使用正则表达式,从技术上讲,module 之前/之后可能有属性、includes 元素内的元素、<includes module='foo>bar'> 等意外字符等。

    最后,如果您的 XML 处于“受控”环境中(即您知道什么可以发生和不可以发生,您知道module 将包含哪些可能的字符,您知道它总是会自闭包含现在孩子等的元素),而不是使用正则表达式。只要知道它正在寻找一组非常特定的规则。但是,如果您希望它适用于“您扔给它的任何东西”..请使用 DOM 解析器(在 Tidy'ing 之后以避免异常),无论性能如何(尽管我敢打赌它在许多实例)。

    另外,最后要注意的是,如果您计划在文档中查找/替换/操作许多节点,那么使用 DOM 解析器会大大提高性能。 DOM 解析器将获取一个文档并对其进行一次解析。然后,您只需遍历它已经加载到其类中的数据。这与使用正则表达式相比,其中每个单独的表达式都将在整个文档中运行以寻找一组匹配项。

    如果您希望我在任何领域更具体(例如,提供Tidywork on a benchmark 示例),请告诉我。

    【讨论】:

    • 嘿,这是一个非常详细的答案!我想我会选择 DOMDocument 和 Tidy,因为我还没有真正进入正则表达式。如果我遇到麻烦,我会告诉你的;)
    • 没问题,如果您对Tidy 有任何问题,请告诉我。如果我没记错and works with XML,它有很多配置选项。我绝对认为DOMDocument 是正确的选择,尽管使用正则表达式总是很有趣;)
    【解决方案2】:

    所以我使用 microtime(true) 做了一些简单的性能测试。事实证明,使用 preg_replace 是更快的选择。 DOM replaceChild 需要 2.0 到 3.5 毫秒,而 preg_replace 需要 0.5 到 1.2 毫秒!但我想那只是在我的情况下。

    这就是我的 html 的样子:

    <!DOCTYPE html>
    <html>
        <head>
            {includes:title}
            {includes:style}
        </head>
        <body>
            {includes:body}
            {includes:footer}
            ...
            allot more here
            ...
        </body>
    </html>
    

    这是使用的正则表达式:/{([ ]*)includes:([ ]*)$key([^}]*)}/i

    正如我所说,我并不完全精通使用正则表达式,但这确实起到了作用。猜猜如果你优化它,它会运行得更快。

    对于 replaceChild 方法,我使用了这样的自定义标签:&lt;includes module='body'/&gt;

    再次,这是我本地服务器上的 testet,因此我仍然需要对它在我的在线服务器上的行为进行一些测试...

    【讨论】:

      猜你喜欢
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多