Signature
mb_ereg_search(?string $pattern = null, ?string $options = null): boolPurpose
mb_ereg_search() runs a multibyte-aware regular expression against a string that was stored earlier by mb_ereg_search_init(). It returns only a boolean: did the pattern match somewhere at or after the current search position? Each successful match moves an internal position to the end of that match, so repeated calls walk through the subject from left to right.
This makes it a stateful, cursor-style API. It differs from mb_ereg(), which takes the subject on every call and does not remember where it stopped. Use mb_ereg_search() when you want to scan one string for several matches in sequence, and use the companion functions to learn what matched and where.
Signature
The function has been available since PHP 4.2.0. As of PHP 8.0.0, both $pattern and $options are nullable.
Parameters and defaults
$pattern: the regular expression, written without delimiters. When it isnull(the default), the pattern from the previous call or frommb_ereg_search_init()is reused.$options: option letters such asifor case-insensitive matching. The letters are explained undermb_regex_set_options(). When it isnull, the default options apply.
The subject string is not a parameter. It comes from mb_ereg_search_init().
The character encoding is the internal encoding, or the one set with mb_regex_encoding(). Setting the encoding explicitly keeps your code independent of configuration.
Return value and failure cases
The function returns true when the string matches and false otherwise. A false result simply means no further match exists from the current position. After a miss, the position moves to the end of the string, so another call also returns false until you reset the position by calling mb_ereg_search_init() again.
To get details of a successful match, call a companion function:
mb_ereg_search_getregs()returns the matched text and capture groups of the last match.mb_ereg_search_getpos()returns the current position, measured in bytes.mb_ereg_search_setpos()moves the position manually.
Example 1: collecting every word
The loop below calls mb_ereg_search() until it returns false. After each hit, mb_ereg_search_getregs() supplies the matched text, with index 0 being the whole match.
mb_regex_encoding('UTF-8');
mb_ereg_search_init('café tea über', '\w+');
$words = [];
while (mb_ereg_search()) {
$match = mb_ereg_search_getregs();
$words[] = $match[0];
}
echo json_encode($words, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";["café","tea","über"]
Example 2: watching the byte position
The position is counted in bytes, not characters. In the string below, ñ takes two bytes in UTF-8, so the first match ends at byte 3 rather than 2. The second match ends at byte 7, the full byte length of the subject.
mb_regex_encoding('UTF-8');
mb_ereg_search_init('añb ñ', 'ñ');
$first = mb_ereg_search();
$pos1 = mb_ereg_search_getpos();
$second = mb_ereg_search();
$pos2 = mb_ereg_search_getpos();
$third = mb_ereg_search();
echo json_encode(['first' => $first, 'pos1' => $pos1, 'second' => $second, 'pos2' => $pos2, 'third' => $third]), "\n";{"first":true,"pos1":3,"second":true,"pos2":7,"third":false}
Example 3: passing a pattern and options
Here the initialisation supplies only the subject. The first search provides the pattern and the i option. Later calls pass nothing and reuse that pattern.
mb_regex_encoding('UTF-8');
mb_ereg_search_init('Alpha beta ALPHA');
$count = 0;
if (mb_ereg_search('alpha', 'i')) {
$count++;
while (mb_ereg_search()) {
$count++;
}
}
echo json_encode(['count' => $count]), "\n";{"count":2}
Edge cases
- Positions are byte offsets. If you need a character offset, convert it yourself, for example by measuring the prefix with
mb_strlen(). - A pattern that can match an empty string needs care in loops, because a match that consumes nothing may not move the cursor forward the way you expect. Prefer patterns that consume at least one character.
- Patterns have no delimiters and no trailing flags. Pass flags through
$options. - The search state is global to the process. Interleaving two scans of different strings will interfere with each other, so finish one scan before starting another.
Common mistakes
- Skipping
mb_ereg_search_init(). The function has no subject of its own. Always set the string first. - Expecting match text as a return value. The return value is a boolean. Fetch text with
mb_ereg_search_getregs()or positions withmb_ereg_search_pos(). - Treating positions as characters. They are bytes, which differ for any non-ASCII text.
- Adding PCRE-style delimiters. Writing
/alpha/imakes the slashes part of the pattern. - Forgetting to reinitialise. Once a scan ends, only a new
mb_ereg_search_init()call, ormb_ereg_search_setpos(), lets you search the same string again. - Assuming the encoding. Call
mb_regex_encoding()so behaviour does not depend on configuration.
Related functions
mb_ereg_search_init()sets the subject and optionally the pattern.mb_ereg_search_pos()andmb_ereg_search_regs()search and return position or groups directly.mb_ereg_search_getregs(),mb_ereg_search_getpos()andmb_ereg_search_setpos()inspect and control the state.mb_regex_encoding()andmb_regex_set_options()control encoding and options.mb_ereg()performs a one-off match without a stored cursor.
Recap
mb_ereg_search() is a boolean, stateful matcher. Initialise the subject, call it repeatedly, and read match details through its companion functions. Remember that positions are bytes, that null arguments reuse earlier settings, and that a failed search exhausts the string until you reinitialise it.
Tested examples
mb_regex_encoding('UTF-8');
mb_ereg_search_init('café tea über', '\w+');
$words = [];
while (mb_ereg_search()) {
$match = mb_ereg_search_getregs();
$words[] = $match[0];
}
echo json_encode($words, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
["café","tea","über"]
mb_regex_encoding('UTF-8');
mb_ereg_search_init('añb ñ', 'ñ');
$first = mb_ereg_search();
$pos1 = mb_ereg_search_getpos();
$second = mb_ereg_search();
$pos2 = mb_ereg_search_getpos();
$third = mb_ereg_search();
echo json_encode(['first' => $first, 'pos1' => $pos1, 'second' => $second, 'pos2' => $pos2, 'third' => $third]), "\n";
{"first":true,"pos1":3,"second":true,"pos2":7,"third":false}
mb_regex_encoding('UTF-8');
mb_ereg_search_init('Alpha beta ALPHA');
$count = 0;
if (mb_ereg_search('alpha', 'i')) {
$count++;
while (mb_ereg_search()) {
$count++;
}
}
echo json_encode(['count' => $count]), "\n";
{"count":2}