预计ereg的寿命,迁移到preg

8
我正在处理一个大型的PHP应用程序(>100万行代码,已有10年历史),它广泛地使用了eregereg_replace - 目前在516个类中共有1768个不同的正则表达式。我深知ereg被弃用的原因,但很明显迁移到preg可能会涉及到大量工作。
有没有人知道ereg支持的维护时间有多长,或者对于这种情况下迁移到preg有什么建议?我怀疑自动从ereg转换到preg是不可能/不切实际的。

1
ereg自PHP 4.1左右就已经被弃用了,但仅仅是因为它不像PCRE函数那样优化。它不太可能很快被移除(至少在神话般的PHP6中不会),即使被移除了,编写一个运行时兼容性支持包装器也很简单(你应该为测试而这样做)。您应该列举一些例子,说明您认为您的posix扩展正则表达式可能不兼容。差异很少显著。 - mario
2
有一些工具可以将ereg转换为preg;例如RegexBuddy,它可以支持COM自动化。根据你的正则表达式的复杂程度以及是否需要迁移,这可能是一个相关的选择。 - Tim Pietzcker
4个回答

2
我的直觉告诉我,他们不会有意删除 ereg。PHP 仍然支持非常古老和已弃用的东西,例如注册全局变量。只是因为有太多过时的应用程序存在了。但是如果有人发现了严重漏洞而没有人修复它,那么这个扩展就有可能被删除。

无论如何,值得注意的是:

  1. 您不必强制升级 PHP 安装。保留过时的服务器来运行遗留应用程序相当普遍。

  2. PHP_Compat PEAR 包提供了一些本地函数的纯 PHP 版本。如果 ereg 消失了,可能会添加它。


顺便说一句...实际上,PHP 6已经死了。他们意识到使PHP完全支持Unicode的方法比他们想象的更加困难,因此他们正在重新考虑所有这些问题。结论是:你永远无法做出完美的预测。

谢谢 - 你上一个链接非常有趣。我们广泛使用多字节/Unicode解析,并拥有大量自定义的实用类来支持它。PHP6 原生支持的承诺使我们既心动又害怕! - Oliver Emberton

2

我不确定ereg何时会被移除,但我猜测可能是在PHP 6.0。

关于你的第二个问题(将ereg转换为preg),这似乎并不难,如果你的应用程序有超过100万行代码,那么你肯定有资源让某人在一周内完成这项工作。我会在你的代码中搜索所有ereg_实例,并在你最喜欢的IDE中设置一些宏(比如添加分隔符、修饰符等)。

我敢打赌,大多数1768个正则表达式都可以使用宏进行移植,其他的,嗯,需要好的眼力。

另一个选择可能是在ereg函数周围编写包装器,如果它们不可用,则根据需要实现更改

if (function_exists('ereg') !== true)
{
    function ereg($pattern, $string, &$regs)
    {
        return preg_match('~' . addcslashes($pattern, '~') . '~', $string, $regs);
    }
}

if (function_exists('eregi') !== true)
{
    function eregi($pattern, $string, &$regs)
    {
        return preg_match('~' . addcslashes($pattern, '~') . '~i', $string, $regs);
    }
}

你明白了。此外,PEAR包PHP Compat 也可能是一个可行的解决方案。

与POSIX正则表达式的区别

从PHP 5.3.0开始,POSIX Regex扩展已被弃用。POSIX正则表达式和PCRE正则表达式之间存在许多差异。本页列出了在转换为PCRE时需要了解的最显著的差异。

  1. PCRE函数要求模式由定界符括起来。
  2. 与POSIX不同,PCRE扩展没有专门的函数进行大小写不敏感匹配。相反,这是使用/i模式修饰符支持的。还有其他模式修饰符可用于更改匹配策略。
  3. POSIX函数查找最左侧匹配的最长匹配,但是PCRE会停止在第一个有效匹配上。如果字符串根本不匹配,则没有任何影响,但如果匹配,则可能对结果匹配和匹配速度产生重大影响。为了说明这种差异,请考虑Jeffrey Friedl的“掌握正则表达式”中的以下示例。在字符串oneselfsufficient上使用one(self)?(selfsufficient)?模式,使用PCRE将导致匹配oneself,但使用POSIX的结果将是完整字符串oneselfsufficient。两个(子)字符串都匹配原始字符串,但POSIX要求最长的是结果。

更为隐晦的方法是使用 "\1" 作为分隔符。这仍然可能失败,但其他典型的分隔符可能已经被使用并且不必要地添加反斜杠 [\-\~]+,因此 addcslashes 可能会撤销那里的转义(是的,太多的条件)。-- 包装函数是唯一明智的方法。在 OP 的情况下,应增加更多测试/警告,并使用 runkit/override_function 进行干运行。 - mario
+1 - 很棒的回答,谢谢(这是我在StackOverflow上的第一个问题,我已经印象深刻!) - Oliver Emberton
@mario:\1是有效的PCRE分隔符吗?我不知道! =)如果它们在ereg的上下文中已经被转义,再次转义波浪线应该没有坏影响...或者应该是addcslashes($pattern, '\\~')?当涉及到转义(未转义)数据时,我真的很糟糕,总是不停地测试它无数次! - Alix Axel
@Oliver:谢谢,希望你能继续留下来!;) - Alix Axel

1

我曾经在一个更小的规模上遇到过这个问题 - 一个类似于10,000行的应用程序。在每种情况下,我所需要做的就是切换到preg_replace()并在正则表达式模式周围放置分隔符。

任何人都应该能够做到这一点 - 即使是非程序员也可以获得文件名和行号列表。

然后只需运行测试以查看是否有任何可以修复的故障。

顺便说一句,ereg函数将从PHP6中删除 - http://jero.net/articles/php6


0

我相信所有的ereg函数将在PHP 6中被移除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接