How can I convert ereg expressions to preg in PHP?
Asked Answered
U

4

154

Since POSIX regular expressions (ereg) are deprecated since PHP 5.3.0, I'd like to know an easy way to convert the old expressions to PCRE (Perl Compatible Regular Expressions) (preg).

Per example, I have this regular expression:

eregi('^hello world');

How can I translate expressions into preg_match compatible expressions?

Note: This post serves as a placeholder for all posts related to conversion from ereg to preg, and as a duplicate options for related questions. Please do not close this question.

Related:

Unwarranted answered 7/6, 2011 at 18:36 Comment(6)
@yes123: Yes, that's the point, I'm tired of it too. I want a wiki post that actually explains something so we can close all these individual questions.Unwarranted
I think no need for this because you just need to wrap the old with a delimiter. Also I think you could have used a previous answered question for this.Gargan
Ah, voted for a close before reading the comments. As a placeholder it could serve a purpose, but isn't there another older question that could've served as such?Medicare
Hmm, indeed. ereg [php] doesn't yield very much useful results. OK, can lend my support to this one.Medicare
@netcoder: acutally I think I answered almost to everything here: #6270193 not to brag out of courseGargan
Folks, we seem to have nearly created a circle of closed questions on this topic all pointing at each other. At this rate they'll all be closed :)Margravine
U
154

The biggest change in the syntax is the addition of delimiters.

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

Delimiters can be pretty much anything that is not alpha-numeric, a backslash or a whitespace character. The most used are generally ~, / and #.

You can also use matching brackets:

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

If your delimiter is found in the regular expression, you have to escape it:

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

You can easily escape all delimiters and reserved characters in a string by using preg_quote:

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

Also, PCRE supports modifiers for various things. One of the most used is the case-insensitive modifier i, the alternative to eregi:

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

You can find the complete reference to PCRE syntax in PHP in the manual, as well as a list of differences between POSIX regex and PCRE to help converting the expression.

However, in your simple example you would not use a regular expression:

stripos($str, 'hello world') === 0
Unwarranted answered 7/6, 2011 at 18:37 Comment(3)
Wonderful explanation! I'd like just to add an special case in which your are converting from ereg to preg_match and you need to escape only the delimiters and not reserved characters (because they were already working as special characters, we don't want to escape them): preg_match('/'.str_replace('/','\/',$expr).'/', $str);Terminus
It's particularly worth noting that if you use matching brackets, then you don't need to escape any characters "just because it's the same as the delimiter" like you do with other symbols like the /^\/hello/ example. (a(b)c) is a perfectly valid, delimited PCRE. I personally like to use parentheses () to remind myself that the first captured match is the entire thing.Messer
how to convert this? $regex = $e . '((\.[^\.' . $e . '][^' . $e . ']*)|(\.\.[^' . $e . ']+)|([^\.][^' . $e . ']*))' . $e . '\.\.' . $e; to preg_math it doest work by just adding / modifier /Countdown
D
36

Ereg replacement with preg(as of PHP 5.3.0) was right move in our favor.

preg_match, which uses a Perl-compatible regular expression syntax, is often a faster alternative to ereg.

You should know 4 main things to port ereg patterns to preg:

  1. Add delimiters(/): 'pattern' => '/pattern/'

  2. Escape delimiter if it is a part of the pattern: 'patt/ern' => '/patt\/ern/'
    Achieve it programmatically in following way:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi(case-insensitive matching): 'pattern' => '/pattern/i' So, if you are using eregi function for case insenstive matching, just add 'i' in the end of new pattern('/pattern/').

  4. ASCII values: In ereg, if you use number in the pattern, it is assumed that you are referring to the ASCII of a character. But in preg, number is not treated as ASCII value. So, if your pattern contain ASCII value in the ereg expression(for example: new line, tabs etc) then convert it to hexadecimal and prefix it with \x.
    Example: 9(tab) becomes \x9 or alternatively use \t.

Demit answered 24/4, 2013 at 6:52 Comment(0)
H
12

From PHP version 5.3, ereg is deprecated.

Moving from ereg to preg_match is just a small change in our pattern.

First, you have to add delimiters to your code, e.g.:

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

to

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

For eregi case-insensitive matching, put i after the last delimiter, e.g.:

eregi('pattern', 'string');

to

preg_match ('/pattern/i', 'string');
Hitlerism answered 12/2, 2016 at 5:52 Comment(0)
C
7

There are more differences between ereg() and preg_replace() than just the syntax:

  • Return value:

    • On error: both return FALSE
    • On no match: ereg() returns FALSE, preg_match() returns 0
    • On match: ereg() returns string length or 1, preg_match() returns always 1
  • Resulting array of matched substrings: If some substring is not found at all ((b) in ...a(b)?), corresponding item in ereg() result will be FALSE, while in preg_match() it will not be set at all.

If one is not brave enough to convert his or her ereg() to preg_match(), he or she may use mb_ereg(), which is still available in PHP 7.

Calvities answered 1/12, 2016 at 15:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.