如何在PHP中将ereg表达式转换为preg?


140

由于自PHP 5.3.0起不推荐使用POSIX正则表达式(例如,egeg),所以我想知道一种将旧表达式转换为PCRE(与Perl兼容的正则表达式)(preg)的简便方法。

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

eregi('^hello world');

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

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

有关:


2
@ yes123:是的,这就是重点,我也对此感到厌倦。我想要一个Wiki帖子,它实际上可以解释某些内容,因此我们可以结束所有这些单个问题。
netcoder 2011年

我认为不需要这样做,因为您只需要用定界符将旧的文件包装起来即可。另外,我认为您可以为此使用先前回答的问题。
动态

嗯,在阅读评论之前投票关闭。作为占位符,它可以达到目的,但是是否还有另一个更老的问题可以解决?
2011年

嗯,的确如此。ereg [php]不会产生非常有用的结果。好的,可以支持我。
2011年

8
伙计们,我们似乎几乎已经围绕这个话题创建了一个封闭的问题圈子,所有这些问题都指向对方。以这种速度,他们都将关闭:)
Kev

Answers:


142

语法上的最大变化是添加了定界符

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支持用于各种事物的修饰符。最常用的一种是不区分大小写的修饰符i,它是eregi的替代品:

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

您可以在手册中找到有关PCRE语法的完整参考,以及差异列表。 POSIX正则表达式和PCRE之间以帮助转换表达式。

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

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

2
精彩的解释!我只想添加一种特殊情况,其中您正在从ereg转换为preg_match,并且您只需要转义定界符而不保留字符(因为它们已经作为特殊字符工作了,我们不想转义它们) : preg_match('/'。str_replace('/','\ /',$ expr)。'/',$ str);
Lolito

这是特别值得一提的是,如果你使用括号匹配,那么你也不需要逃避任何字符“只是因为它是一样的分隔符”像你一样的其他符号做/^\/hello/例子。(a(b)c)是完全有效的定界PCRE。我个人喜欢用括号()提醒自己,第一个被捕获的匹配是整个过程。
Niet the Dark Absol

我可以说,我非常讨厌PHP!(仅此而已。没什么。)当我的共享Web托管服务器更新为新版本并且error_logs出现以下警告时,我必须搜索这些答案:PHP Deprecated: Function ereg() is deprecated in...。啊!
c00000fd

如何转换呢?$ regex = $ e。'((\。[^​​ \。'。$ e。'] [^'。$ e。'] *)|(\。\。[^'。$ e。'] +)|([^ \。 ] [^'。$ e。'] *))'。$ e。'\。\。' 。$ e; 到preg_math它
不能通过

32

用preg(从PHP 5.3.0开始)替换Ereg是对我们有利的正确举动。

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

您应该了解4个将ereg模式移植到preg的主要知识:

  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.


8

从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');

7

ereg()和之间的区别preg_replace()不仅仅是语法:

  • 返回值:

    • 错误时:两者都返回FALSE
    • 无匹配时ereg()return FALSEpreg_match()returns0
    • 匹配时ereg()返回字符串长度或1preg_match()始终返回1
  • 匹配的子字符串的结果数组:如果根本找不到某个子字符串((b)在中...a(b)?),则ereg()结果中的对应项将为FALSE,而preg_match()其中的任何项都将不会设置。

如果不够勇敢地将其转换ereg()preg_match(),则可以使用mb_ereg(),该版本在PHP 7中仍然可用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.