Signature
mb_ereg(string $pattern, string $string, array &$matches = null): boolPurpose
mb_ereg() checks whether a regular expression matches a string, and it does so with awareness of multibyte characters. A single character such as ö or é takes more than one byte in UTF-8. Because the engine reads characters instead of raw bytes, a dot in the pattern stands for one whole character. This is the main reason to choose it over a byte-oriented tool when you work with non-ASCII text.
The function belongs to the mbstring extension and uses the character encoding set with mb_regex_encoding(), or the internal encoding if you have not set one. Setting the encoding explicitly keeps your code predictable.
Signature
Parameters and defaults
$pattern: the search pattern. It is written without delimiters, unlike thepreg_*family. Write'(\d+)-(\d+)', not'/(\d+)-(\d+)/'.$string: the text to search. The match may start anywhere in it, so there is no need to add a leading.*. Use^and$when you want to anchor the pattern.$matches: optional, passed by reference, defaultnull. When you pass a variable, it receives the captured text. Index0holds the whole match, index1the first parenthesized group, index2the second, and so on.
Return value and failure cases
Since PHP 8.0 the function returns a plain bool: true when the pattern matches and false when it does not. Older versions returned the byte length of the match, which is why code written for PHP 7 sometimes compares the result to numbers. In PHP 8.4, treat the result strictly as a boolean.
When nothing matches and you passed $matches, the variable is set to an empty array. A malformed pattern is a different problem from a non-match, so test your patterns with known input before shipping them.
Example: capturing groups
The first example extracts two numbers from the middle of a string. The match is not anchored, so it is found even though the text starts with other words.
mb_regex_encoding('UTF-8');
$found = mb_ereg('(\d+)-(\d+)', 'Room 12-34', $matches);
echo json_encode([$found, $matches], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[true,["12-34","12","34"]]
Example: one dot, one character
Here the dot has to consume the two-byte letter ö. With the encoding set to UTF-8, the engine treats it as a single character and captures it whole.
mb_regex_encoding('UTF-8');
$found = mb_ereg('w(.)rld', 'wörld', $matches);
echo json_encode([$found, $matches], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[true,["wörld","ö"]]
Example: no match
When the pattern does not match, the function returns false and $matches becomes an empty array. You can rely on that instead of checking whether the variable is defined.
mb_regex_encoding('UTF-8');
$found = mb_ereg('[0-9]+', 'abc', $matches);
echo json_encode([$found, $matches], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[false,[]]
Edge cases
- Matches are strings. Captured digits come back as strings such as
"12", not integers. Cast them yourself if you need numbers. - Encoding matters. If the regex encoding does not agree with the encoding of your data, characters can be split in the wrong places and the result will be unreliable. Call
mb_regex_encoding('UTF-8')before matching UTF-8 text. - No flags after the pattern. Because there are no delimiters, you cannot append modifiers such as
i. For a case-insensitive match, use the sibling functionmb_eregi(). - Matching with an empty-length result. A pattern that can match nothing, such as one made only of optional parts, still returns
true. Do not use the length of the match as a success signal.
Common mistakes
- Adding delimiters. Writing
'/abc/'makes the slashes part of the pattern, so it looks for literal slashes and usually fails. - Comparing the result with integers. Code such as
mb_ereg(...) > 0comes from the pre-8.0 return value. Test the boolean directly. - Reading
$matcheswithout checking the result. Check the return value first; on failure the array is empty, so$matches[1]does not exist. - Assuming
preg_match()syntax. The engine and its syntax differ from PCRE, so features such as the/umodifier, named-group syntax or delimiters should not be carried over blindly. - Leaving the encoding implicit. Relying on a default makes behavior depend on configuration. Set the encoding in the code.
Related functions
mb_eregi(): the same match, ignoring case.mb_regex_encoding(): gets or sets the character encoding used by themb_ereg*functions.preg_match(): the delimiter-based PCRE alternative, often used with theumodifier for UTF-8.
Recap
mb_ereg() takes a delimiter-free pattern, searches the string for a match anywhere in it, and returns a boolean. Pass a variable as the third argument to receive the full match and each captured group as strings, with an empty array when nothing matches. Set the regex encoding first so that each character is treated as one unit, and use mb_eregi() when case should not matter.
Tested examples
mb_regex_encoding('UTF-8');
$found = mb_ereg('(\d+)-(\d+)', 'Room 12-34', $matches);
echo json_encode([$found, $matches], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
[true,["12-34","12","34"]]
mb_regex_encoding('UTF-8');
$found = mb_ereg('w(.)rld', 'wörld', $matches);
echo json_encode([$found, $matches], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
[true,["wörld","ö"]]
mb_regex_encoding('UTF-8');
$found = mb_ereg('[0-9]+', 'abc', $matches);
echo json_encode([$found, $matches], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
[false,[]]