Signature
mb_ereg_replace_callback(
string $pattern,
callable $callback,
string $string,
?string $options = null
): string|false|nullPurpose
mb_ereg_replace_callback() searches a string for matches of a multibyte-aware regular expression and replaces each match with whatever a callback returns. Use it when a fixed replacement string is not enough: the new text has to be computed from the matched text, for example by incrementing a number, measuring a word or normalising a spelling.
It behaves almost like mb_ereg_replace(), except that you supply a callback instead of a replacement string. It belongs to the mb_ereg* family, which uses its own pattern syntax and is separate from the PCRE preg_* functions.
Signature
Parameters and defaults
$pattern: the regular expression. It is written without delimiters, and it may contain multibyte characters.$callback: any PHP callable. It receives one array of matched elements. Index0is the whole match and1,2and so on are the parenthesised groups. It should return the replacement string.$string: the subject text to scan.$options: optional search option letters, such asifor case-insensitive matching. The default isnull; seemb_regex_set_options()for the available letters.optionshas been nullable since PHP 8.0.0.
The character encoding used is the internal encoding or the one set with mb_regex_encoding(). Set it explicitly when your text is UTF-8 so the result does not depend on configuration.
Return value and failure cases
On success you get the resulting string. If the text contains no matches, you get the subject back unchanged. The function returns false on error. If $string is not valid for the current encoding, it returns null. Because the return type is a union, compare strictly (=== null, === false) rather than relying on truthiness, since an empty string is a legitimate successful result.
Example 1: computing a replacement
The callback receives the groups, so it can do arithmetic on one of them and keep the rest.
$text = "Due 04/01/2002 and 12/24/2001";
echo mb_ereg_replace_callback(
'(\d{2}/\d{2}/)(\d{4})',
fn(array $m): string => $m[1] . ((int) $m[2] + 1),
$text
), "\n";Due 04/01/2003 and 12/24/2002
Each date keeps its day and month prefix while the year is increased by one.
Example 2: multibyte words
With the encoding set to UTF-8, a word pattern treats accented letters as single characters, and mb_strlen() in the callback counts characters instead of bytes.
mb_regex_encoding('UTF-8');
$text = 'naïve café';
echo mb_ereg_replace_callback(
'\w+',
fn(array $m): string => '[' . $m[0] . ':' . mb_strlen($m[0], 'UTF-8') . ']',
$text
), "\n";[naïve:5] [café:4]
Example 3: options and a counter
The i option makes matching case-insensitive. A closure can capture a variable by reference to record how many replacements happened.
$text = 'php, Php and PHP';
$count = 0;
$result = mb_ereg_replace_callback(
'php',
function (array $m) use (&$count): string {
$count++;
return 'PHP';
},
$text,
'i'
);
echo json_encode(['text' => $result, 'count' => $count]), "\n";{"text":"PHP, PHP and PHP","count":3}
Edge cases
- A pattern that matches nothing leaves the subject untouched, and the callback is never called.
- The callback runs once per match, from left to right, so keep it cheap and free of side effects you cannot repeat.
- Group numbers follow the order of opening parentheses. If you add a group at the start of a pattern, the indexes you use in the callback shift.
- Invalid input for the active encoding produces
null, not a partially converted string.
Common mistakes
- Using PCRE delimiters. Writing
'/\d+/'treats the slashes as literal characters. Write'\d+'instead. - Passing a replacement string. The second argument must be callable. A plain string is interpreted as a function name, which is almost never what you want.
- Forgetting to return. A callback that echoes or has no
returndoes not provide the replacement text you intended. - Ignoring encoding. Without a deliberate encoding, byte-based assumptions creep in. Call
mb_regex_encoding('UTF-8')and usemb_*string functions inside the callback. - Loose result checks. Test for
falseandnullstrictly before using the result as text.
Related functions
mb_ereg_replace()for a fixed replacement string with the same pattern syntax.mb_regex_encoding()to get or set the regex encoding.mb_regex_set_options()to see the option letters.preg_replace_callback()for the PCRE equivalent.
Recap
mb_ereg_replace_callback() replaces every match of a delimiter-free, multibyte-aware pattern with the string your callback returns. The callback receives an array of the whole match and its groups. The function returns the new string, false on error, or null for input that is invalid in the current encoding, so check the result strictly.
Tested examples
$text = "Due 04/01/2002 and 12/24/2001";
echo mb_ereg_replace_callback(
'(\d{2}/\d{2}/)(\d{4})',
fn(array $m): string => $m[1] . ((int) $m[2] + 1),
$text
), "\n";
Due 04/01/2003 and 12/24/2002
mb_regex_encoding('UTF-8');
$text = 'naïve café';
echo mb_ereg_replace_callback(
'\w+',
fn(array $m): string => '[' . $m[0] . ':' . mb_strlen($m[0], 'UTF-8') . ']',
$text
), "\n";
[naïve:5] [café:4]
$text = 'php, Php and PHP';
$count = 0;
$result = mb_ereg_replace_callback(
'php',
function (array $m) use (&$count): string {
$count++;
return 'PHP';
},
$text,
'i'
);
echo json_encode(['text' => $result, 'count' => $count]), "\n";
{"text":"PHP, PHP and PHP","count":3}