38

我注意到在 PHP regex 库中有 ereg 和 preg 之间的选择。有什么不同?一个比另一个快,如果是这样,为什么不弃用较慢的一个?

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

4

5 回答 5

42

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

警告

自 PHP 5.3.0 起,该函数已被弃用,自 PHP 6.0.0 起已移除。强烈建议不要依赖此功能。

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

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

注意我的重点。

于 2009-09-01T10:00:54.837 回答
19

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

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

于 2009-09-01T10:00:20.253 回答
5

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

如果您计划在某一天升级到 PHP6,那么您的决定就完成了。除此以外:

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

在 PHP 中弃用 POSIX 正则表达式以进行 Perl 搜索就像用木板和砖块代替带有预制房间和墙壁的房子。当然,您也许可以混合和匹配一些零件,但是将所有零件摆在您面前进行修改会容易得多。

PCRE 比 POSIX RE 快?不总是。在 Cynergi 最近的一个搜索引擎项目中,我有一个简单的循环,其中包含一些可爱的 ereg_replace() 函数,需要 3 分钟来处理数据。我把那个 10 行的循环改成了一个 100 行的手写代码来替换,现在这个循环需要 10 秒来处理相同的数据!这让我看到了在某些情况下可以做什么是很慢的正则表达式。最近我决定研究 Perl 兼容的正则表达式 (PCRE)。大多数页面声称 PCRE 比 POSIX 更快,但也有一些页面声称不是这样。我决定了我自己的基准。我的前几次测试证实 PCRE 更快,但是......结果与其他人得到的结果略有不同,所以我决定对我在 8000 行安全(和快速)Webmail 项目中的每个 RE 使用情况进行基准测试,网址为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 中比转换为 PCRE 时快 30%(即使您使用 \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 中快 2.5 倍。简单的替换模式,例如 ereg_replace("[^a-zA-Z0-9-]+", "", $m); POSIX RE 比 PCRE 快 2 倍。by[ \t]+([^ \t]+)[ \t]/i 比它的 POSIX RE 版本快 30 倍!在区分大小写方面,到目前为止,PCRE 似乎是最佳选择。但我从 ereg/eregi 发现了一些非常奇怪的行为。在一个非常简单的 POSIX RE (^|\r|\n)mime-version[ \t]:我发现 eregi() 需要 3.60 秒(只是测试基准中的一个数字),而相应的 PCRE 需要 0.16 秒!但是如果我使用 ereg() (区分大小写),POSIX RE 时间会下降到 0.08 秒!于是我进一步调查。我试图使 POSIX RE 本身不区分大小写。我得到了这个: (^|\r|\n)[mM][iI][mM][eE]-vers[iI][oO][nN][ \t]*:这个版本也花了 0.08 s。但是,如果我尝试将相同的规则应用于任何未更改的“v”、“e”、“r”或“s”字母,时间就会回到 3.60 秒标记,而不是逐渐地,而是立即所以!测试数据中没有任何“vers”、其他“mime”词或任何可能混淆 POSIX 解析器的“ion”,所以我不知所措。底线:始终对您的 PCRE / POSIX RE 进行基准测试以找到最快的!在 Windows 下,从命令行使用 PHP 5.1.2 执行了测试。Pedro Freire cynergi.com

于 2009-09-01T10:30:12.393 回答
4

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

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

于 2011-06-24T17:51:35.097 回答
3

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

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

于 2009-09-01T10:01:20.827 回答