【问题标题】:How can I convert ereg expressions to preg in PHP?如何在 PHP 中将 ereg 表达式转换为 preg?
【发布时间】:2020-04-27 13:39:45
【问题描述】:

由于自 PHP 5.3.0 起已弃用 POSIX regular expressions (ereg),我想知道一种将旧表达式转换为 PCRE (Perl Compatible Regular Expressions) (preg) 的简单方法。

例如,我有这个正则表达式:

eregi('^hello world');

如何将表达式转换为preg_match 兼容的表达式?

注意:此帖子用作所有与从 ereg 转换为 preg 相关的帖子的占位符,并作为相关问题的重复选项。请不要关闭此问题。

相关:

【问题讨论】:

  • @yes123:是的,这就是重点,我也厌倦了。我想要一个 wiki 帖子,它实际上解释了一些事情,这样我们就可以关闭所有这些单独的问题。
  • 我认为不需要这个,因为你只需要用分隔符包裹旧的。另外,我认为您可以为此使用先前已回答的问题。
  • 啊,在阅读 cmets 之前投票赞成关闭。作为占位符,它可以起到一定的作用,但难道没有另一个更老的问题可以起到这样的作用吗?
  • 嗯,确实。 ereg [php] 不会产生非常有用的结果。好的,可以支持一下这个。
  • 伙计们,我们似乎在这个话题上几乎创建了一个封闭的问题圈,都指向对方。按照这个速度,它们都会被关闭:)

标签: php preg-replace preg-match pcre ereg


【解决方案1】:

从 PHP 5.3 版开始,ereg 已弃用。

ereg 移动到preg_match 只是我们模式的一个小变化。

首先,您必须在代码中添加分隔符,例如:

ereg('A-Z0-9a-z', 'string');

preg_match('/A-Z0-9a-z/', 'string');

对于eregi不区分大小写的匹配,将i放在最后一个分隔符之后,例如:

eregi('pattern', 'string');

preg_match ('/pattern/i', 'string');

【讨论】:

    【解决方案2】:

    用 preg 替换 Ereg(从 PHP 5.3.0 开始)对我们有利。

    preg_match 使用与 Perl 兼容的正则表达式语法,通常比 ereg 更快。

    您应该知道将 ereg 模式移植到 preg 的 4 个主要事项:

    1. 添加分隔符(/):'pattern' => '/pattern/'

    2. 转义分隔符如果它是模式的一部分:'patt/ern' => '/patt\/ern/'
      通过以下方式以编程方式实现它:
      $old_pattern = '<div>.+</div>';
      $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

    3. eregi(不区分大小写匹配):'pattern' => '/pattern/i' 因此,如果您使用eregi 函数进行不区分大小写的匹配,只需在新模式('/pattern/') 的末尾添加'i'。

    4. ASCII 值:在ereg 中,如果在模式中使用数字,则假定您指的是字符的ASCII。但在 preg 中,数字不被视为 ASCII 值。因此,如果您的模式在 ereg 表达式中包含 ASCII 值(例如:新行、制表符等),则将其转换为十六进制并在其前面加上 \x。
      Example: 9(tab) becomes \x9 or alternatively use \t.

    【讨论】:

      【解决方案3】:

      语法上最大的变化是增加了delimiters

      ereg('^hello', $str);
      preg_match('/^hello/', $str);
      

      分隔符几乎可以是任何非字母数字、反斜杠或空白字符。用得最多的一般是~/#

      你也可以使用匹配的括号:

      preg_match('[^hello]', $str);
      preg_match('(^hello)', $str);
      preg_match('{^hello}', $str);
      // etc
      

      如果在正则表达式中找到您的分隔符,则必须对其进行转义:

      ereg('^/hello', $str);
      preg_match('/^\/hello/', $str);
      

      您可以使用preg_quote轻松转义字符串中的所有分隔符和保留字符:

      $expr = preg_quote('/hello', '/');
      preg_match('/^'.$expr.'/', $str);
      

      另外,PCRE 支持modifiers 处理各种事情。最常用的修饰符之一是不区分大小写的修饰符i,是eregi 的替代品:

      eregi('^hello', 'HELLO');
      preg_match('/^hello/i', 'HELLO');
      

      您可以找到对 PCRE syntax in PHP in the manual 的完整引用,以及 POSIX 正则表达式和 PCRE 之间的 list of differences 以帮助转换表达式。

      但是,在您的简单示例中,您不会使用正则表达式:

      stripos($str, 'hello world') === 0
      

      【讨论】:

      • 精彩的解释!我只想添加一个特殊情况,您正在从 ereg 转换为 preg_match 并且您只需要转义分隔符而不是保留字符(因为它们已经作为特殊字符工作,我们不想转义它们):preg_match('/'.str_replace('/','\/',$expr).'/', $str);
      • 特别值得注意的是,如果您使用匹配的括号,那么您不需要像您一样“仅仅因为它与分隔符相同”而转义任何字符其他符号,例如 /^\/hello/ 示例。 (a(b)c) 是一个完全有效的分隔 PCRE。我个人喜欢用括号() 来提醒自己,第一个捕获的匹配就是整个事件。
      • 如何转换? $正则表达式 = $e 。 '((\.[^\.' . $e . '][^' . $e . ']*)|(\.\.[^' . $e . ']+)|([^\. ][^' . $e . ']*))' . $e 。 '\.\.' . $e; preg_math 只需添加 / 修饰符 / 即可
      【解决方案4】:

      ereg()preg_replace() 之间的区别不仅仅在于语法:

      • 返回值:

        • 出错:两者都返回 FALSE
        • 不匹配ereg() 返回FALSEpreg_match() 返回0
        • 匹配时ereg() 返回字符串长度或1preg_match() 总是返回1
      • 匹配子字符串的结果数组:如果根本找不到某个子字符串(...a(b)? 中的(b)),则ereg() 结果中的对应项将为FALSE,而在preg_match() 中则为根本没有设置。

      如果一个人没有足够的勇气将他或她的ereg() 转换为preg_match(),他或她可以使用mb_ereg(),它在 PHP 7 中仍然可用。

      【讨论】:

        猜你喜欢
        • 2010-12-02
        • 2011-03-05
        • 2010-11-24
        • 2012-12-09
        相关资源
        最近更新 更多