【问题标题】:PHP ereg vs. pregPHP ereg 与 preg
【发布时间】:2010-11-24 14:22:02
【问题描述】:

我注意到在 PHP 正则表达式库中有 ereg 和 preg 之间的选择。有什么区别?一个比另一个快吗?如果是,为什么不弃用较慢的那个?

在任何情况下使用一种比另一种更好吗?

【问题讨论】:

    标签: php regex pcre posix-ere


    【解决方案1】:

    访问 php.net/ereg 显示如下:

    警告

    从 PHP 5.3.0 开始,该函数已被弃用,并从 PHP 6.0.0 开始删除。强烈建议不要依赖此功能。

    再往下走一点,我们就读到了:

    注意:preg_match() 使用与 Perl 兼容的正则表达式语法,通常是 ereg() 更快的替代方法。

    注意我的重点。

    【讨论】:

    • 啊,好的,谢谢,不知什么原因我没看到。再见,我想!接受的答案。
    • 正如 Percy 指出的,mb_ereg_match() 和其他多字节 ereg 函数并未被弃用。
    【解决方案2】:

    preg 是 Perl 兼容的正则表达式库
    ereg 是 POSIX 兼容的正则表达式库

    它们的语法稍有不同,而 preg 在某些情况下稍快一些。 ereg 已弃用(在 php6 中已删除),因此我不建议使用它。

    【讨论】:

      【解决方案3】:

      关于哪个更快更好的讨论很多。

      如果您计划有一天升级到 PHP6,那么您的决定已经做出。否则:

      普遍的共识是 PCRE 是更好的全方位解决方案,但如果您有一个流量很大的特定页面,并且您不需要 PHP6,则可能值得进行一些测试。 例如,来自 PHP 手册 cmets:

      在 PHP 中弃用 POSIX 正则表达式 Perl 搜索就像替换 房子的木板和砖 预制房间和墙壁。 当然,你可以混搭 一些部分,但很多 更容易修改所有部分 摆在你面前。

      PCRE 比 POSIX RE 快?不总是。 在最近的一个搜索引擎项目中 在 Cynergi,我有一个简单的循环 几个可爱的 ereg_replace() 函数 处理数据需要 3 分钟。我变了 那 10 行循环成 100 行 用于替换的手写代码和 循环现在需要 10 秒来处理 一样的数据!这让我大开眼界 在某些情况下会很慢吗 常用表达。最近我决定 查看 Perl 兼容的常规 表达式(PCRE)。大多数页面声称 PCRE 比 POSIX 快,但有一些 否则索赔。我决定 我自己的标杆。我的前几个 测试证实 PCRE 更快, 但是……结果稍微有点 与其他人不同,所以 我决定对每个案例进行基准测试 我在 8000 线安全上的 RE 使用情况 (和快速)Webmail 项目在这里 Cynergi 来检查一下。结果? 无定论!有时 PCRE 更快(有时更大的一个因素 比快 100 倍!),但其他一些 POSIX RE 的时间更快(一个因素 2 倍)。我仍然需要找到一个规则 什么时候一个或另一个更快。它是 不仅与搜索数据大小有关, 匹配的数据量,或“RE 编译时间”这将显示 当您经常重复该功能时: 一个会总是比 其他。但是我没有找到模式 这里。但说实话,我也没有 花时间调查源头 编码并分析问题。我能 不过,给你一些例子。这 POSIX RE ([0-9]{4})/([0-9]{2})/([0-9]{2})[^0-9]+ ([0-9]{2}):([0-9]{2}):([0-9]{2}) 是 在 POSIX 中比在 POSIX 中快 30% 转换为 PCRE(即使您使用 \d 和 \D 和非贪婪匹配)。在 另一方面,类似的 PCRE 复杂模式 /[0-9]{1,2}[ \t]+[a-zA-Z]{3}[ \t]+[0-9]{4}[ \t]+[0-9]{1,2}:[0-9]{1,2}(:[0-9]{1,2})?[ \t]+[+-][0-9]{4}/ 在 PCRE 比在 POSIX RE 中。简单的 替换模式如 ereg_replace("[^a-zA-Z0-9-]+", "", $m );在 POSIX RE 中比在 POSIX RE 中快 2 倍 聚合酶链反应。然后我们又糊涂了 因为 POSIX RE 模式 (^|\n|\r)begin-base64[ \t]+[0-7]{3,4}[ \t]+...... 比 POSIX RE 快 2 倍, 但不区分大小写的 PCRE /^收到[ \t]*:[ \t]by[ \t]+([^ \t]+)[ \t]/i 比它的速度快 30 倍 POSIX RE 版本!到那个时刻 区分大小写,PCRE 到目前为止 似乎是最好的选择。但是我 发现了一些非常奇怪的行为 来自 ereg/eregi。在一个非常简单的 POSIX RE (^|\r|\n)mime 版本[\t]: 我发现 eregi() 需要 3.60 秒(只是 测试基准中的数字),而 对应的PCRE耗时0.16s!但如果 我使用了 ereg() (区分大小写) POSIX RE 时间降至 0.08 秒!所以我 进一步调查。我试着做 POSIX RE 本身不区分大小写。 我做到了这一点: (^|\r|\n)[mM][iI][mM][eE]-vers[iI][oO][nN][ \t]*:这个版本也花了 0.08s。 但是,如果我尝试将相同的规则应用于 'v'、'e'、'r' 或 's' 中的任何一个 没有改变的字母,时间 回到 3.60 年代大关,而不是 逐渐地,但立即如此!这 测试数据中没有任何“版本” 它,其中的其他“哑剧”词或任何 可能会混淆的“离子” POSIX解析器,所以我很茫然。底部 行:始终对您的 PCRE 进行基准测试 / POSIX RE找最快!测试 在 PHP 5.1.2 下执行 Windows,从命令行。佩德罗 Freire cynergi.com

      【讨论】:

        【解决方案4】:

        尽管 ereg 在 PHP 5.3 中已被弃用,但 mb_ereg* 函数并未被弃用。我认为主要原因是 PHP6 正在重建所有 MB/Unicode 支持,因此旧的“常规”ereg 方法没有用,因为 mb_ereg 会更新/更好。

        我知道它不能回答有关速度的问题,但它确实允许您继续使用 POSIX 和 PCRE。

        【讨论】:

          【解决方案5】:

          嗯,ereg 及其派生函数(ereg_match 等)在 php5 中已被弃用,并在 php6 中被删除,因此您最好使用 preg 系列。

          preg 是 Perl 风格的正则表达式,而 ereg 是标准的 POSIX 正则表达式。

          【讨论】:

            猜你喜欢
            • 2010-12-02
            • 2011-03-05
            • 2011-09-23
            • 2020-04-27
            相关资源
            最近更新 更多