Learn how to transition from ereg_replace() to preg_replace() in PHP for more efficient regex handling, improving performance and compatibility in your applications.
If you’ve kept an old PHP app alive long enough, you’ve probably hit the wall: you bump the server to PHP 7 and the whole thing dies with Call to undefined function ereg_replace(). That function was deprecated in PHP 5.3 and removed outright in PHP 7.0, so on any modern server it simply isn’t there anymore.
The fix is preg_replace(). It’s been the right tool for years, it runs on the PCRE (Perl-Compatible Regular Expressions) engine, and it does everything ereg_replace() did plus a lot more. The catch is that the patterns aren’t drop-in compatible, so you can’t just swap the function name and walk away. Here’s what actually changes and how to move your code across.
Why the switch isn’t optional
This isn’t a style preference. ereg_replace() lived in the old ereg extension, which used POSIX regular expressions. That whole extension is gone in PHP 7+, so keeping it means you’re stuck on PHP 5, and PHP 5 stopped getting security fixes years ago. A few concrete reasons the move is worth it:
- It still runs.
preg_replace()ships with PHP and works on every supported version. Your code keeps running when the host upgrades. - PCRE is more capable. You get lookaheads, lookbehinds, non-capturing groups, and Unicode support, none of which POSIX regex handled well.
- Performance. The PCRE engine is generally faster than the old POSIX matching, especially on non-trivial patterns.
What’s different about the patterns
Both functions search a string and replace what they match, so the shape of your code barely moves. The regex syntax is where you have to pay attention:
- Delimiters. This is the one that bites everyone.
preg_replace()needs delimiters around the pattern, usually slashes (/pattern/).ereg_replace()took a bare string. Forget the delimiters and you get a warning and aNULLback. - Modifiers. PCRE lets you tack flags on after the closing delimiter:
ifor case-insensitive,mfor multiline,ufor Unicode. POSIX had no equivalent. - Case handling. Both
ereg_replace()andpreg_replace()are case-sensitive by default. The old case-insensitive behavior came from a separate function,eregi_replace(), not fromereg_replace()itself. With PCRE there’s no separate function: you just add theimodifier.
Step 1: Understanding preg_replace()
preg_replace() searches a string for a pattern, swaps every match for your replacement, and returns the new string. The signature you’ll use most looks like this:
preg_replace(pattern, replacement, subject[, limit])
- pattern: The regular expression to search for.
- replacement: The string to replace the matches with.
- subject: The input string to search within.
- limit: (Optional) The maximum number of replacements. Defaults to -1, which means no limit.
Example 1: Basic preg_replace() Usage
Start simple. Swap one word for another:
<?php
$string = 'The quick brown fox jumps over the lazy dog';
$pattern = '/fox/';
$replacement = 'cat';
$result = preg_replace( $pattern, $replacement, $string );
echo $result;
// Output: The quick brown cat jumps over the lazy dog
?>Step 2: Converting your old calls
Most conversions come down to wrapping the pattern in delimiters and adjusting anything POSIX-specific. Here’s the kind of call you’re migrating away from:
Example 2: Simple Conversion from ereg_replace() to preg_replace()
<?php
$string = 'abc123';
$pattern = '[a-z]';
$replacement = 'X';
$result = ereg_replace( $pattern, $replacement, $string );
echo $result;
// Output: XXXXXX
?>Same logic, PCRE-ready. The only change is the slashes around the pattern:
<?php
$string = 'abc123';
$pattern = '/[a-z]/';
$replacement = 'X';
$result = preg_replace( $pattern, $replacement, $string );
echo $result;
// Output: XXX123
?>Example 3: Matching Case-Insensitively
If your old code relied on eregi_replace() for case-insensitive matching, don’t reach for a second function. Add the i modifier after the closing delimiter and preg_replace() handles it:
<?php
$string = 'abc123ABC';
$pattern = '/abc/i';
$replacement = 'XYZ';
$result = preg_replace($pattern, $replacement, $string);
echo $result;
// Output: XYZ123XYZ
?>Step 3: The stuff POSIX couldn’t do
Once you’re on PCRE, you get features the old engine never had. A few worth knowing.
Example 4: Using Backreferences in preg_replace()
Backreferences let you reuse part of a match inside the replacement, so you can keep some of the original text while rewriting the rest:
<?php
$string = 'Hello 123, this is number 456.';
$pattern = '/(\d+)/';
$replacement = '[$1]';
$result = preg_replace( $pattern, $replacement, $string );
echo $result;
// Output: Hello [123], this is number [456].
?>Example 5: Using Lookaheads and Lookbehinds
Lookaheads and lookbehinds match a pattern only when it is (or isn’t) followed or preceded by something else, without consuming that context. Here we replace apple only when pie comes next:
<?php
$string = 'apple pie, apple tart, apple juice';
$pattern = '/apple(?=\s+pie)/';
$replacement = 'orange';
$result = preg_replace( $pattern, $replacement, $string );
echo $result;
// Output: orange pie, apple tart, apple juice
?>Example 6: Replacing Multiple Patterns Simultaneously
Pass arrays instead of strings and preg_replace() runs each pattern against the subject in order, which saves you a stack of nested calls:
<?php
$string = 'The quick brown fox jumps over the lazy dog.';
$patterns = array( '/quick/', '/brown/', '/lazy/' );
$replacements = array( 'slow', 'green', 'active' );
$result = preg_replace( $patterns, $replacements, $string );
echo $result;
// Output: The slow green fox jumps over the active dog.
?>When a plain replacement isn’t enough: preg_replace_callback()
Sometimes the replacement depends on the match itself, and a static string won’t cut it. That’s what preg_replace_callback() is for: it runs your function on every match and uses the return value as the replacement.
Example 7: Reversing Words Using preg_replace_callback()
<?php
$string = 'Hello world!';
$pattern = '/\b(\w+)\b/';
$result = preg_replace_callback( $pattern, function( $matches ) {
return strrev( $matches[0] );
}, $string);
echo $result;
// Output: olleH dlrow!
?>The takeaway
Moving off ereg_replace() isn’t busywork. It’s what keeps your code running on a supported PHP version that still gets security patches. The mechanical part is small: add delimiters, drop eregi_replace() in favor of the i modifier, and check any POSIX-specific syntax.
Do it once, test your patterns against real input, and you’re on the modern engine for good. Everything you build after that gets lookaheads, Unicode, and callbacks for free.


