Mb eregi: примеры (PHP)

Поиск в многобайтовых строках PHP с помощью mb_eregi
Раздел: Многобайтовые строки
mb_eregi(string $pattern, string $string, array &$matches = null): bool

Функция mb_eregi в PHP

Общее описание

Функция mb_eregi выполняет регистронезависимый поиск соответствия регулярному выражению в многобайтовой строке. Она является частью модуля mbstring, предназначенного для корректной работы со строками в многобайтовых кодировках, таких как UTF-8. Функция особенно полезна при обработке текстов на языках с нелатинской письменностью.

Аргументы функции

Синтаксис:
mb_eregi(string $pattern, string $string, array &$matches = null): bool

  1. $pattern (string): Искомое регулярное выражение. Регистр символов игнорируется.
  2. $string (string): Строка, в которой выполняется поиск.
  3. &$matches (array, опционально): Если передан, то в него будут помещены результаты поиска. Первый элемент массива содержит весь найденный текст, последующие - подвыражения в круглых скобках.

Функция возвращает true, если найдено соответствие шаблону, и false в противном случае.

Простые примеры использования

Базовый поиск

Поиск слова независимо от регистра.

<?php
$string = 'Привет, мир!';
if (mb_eregi('мир', $string)) {
    echo 'Найдено';
} else {
    echo 'Не найдено';
}
?>
Найдено
Использование matches

Извлечение части строки.

<?php
$string = 'Иван Иванов';
$found = mb_eregi('иван', $string, $matches);
var_dump($found, $matches);
?>
bool(true)
array(1) {
  [0]=>
  string(8) "Иван"
}
Работа с подвыражениями

Извлечение имени и фамилии.

<?php
$string = 'Анна Петрова';
mb_eregi('([а-я]+)\s+([а-я]+)', $string, $matches);
print_r($matches);
?>
Array
(
    [0] => Анна Петрова
    [1] => Анна
    [2] => Петрова
)

Похожие функции в PHP

mb_ereg

Функция mb_ereg аналогична mb_eregi, но является регистрозависимой. Её предпочтительнее использовать, когда важно различать заглавные и строчные буквы.

preg_match

Функция preg_match из расширения PCRE также поддерживает многобайтовые строки с модификатором u. Она часто работает быстрее и обладает более богатым синтаксисом регулярных выражений. Для регистронезависимого поиска используется модификатор i.

Сравнение
  • mb_eregi/mb_ereg: Часть модуля mbstring, проще для базовых операций в известной кодировке.
  • preg_match: Более современный и мощный инструмент, рекомендуется для новых проектов.

Типичные ошибки

Неверная кодировка

Если внутренняя кодировка скрипта не совпадает с кодировкой строки, поиск может завершиться неудачей.

<?php
mb_internal_encoding('CP1251'); // Устанавливаем Windows-1251
$string = 'Тест'; // В UTF-8
$result = mb_eregi('тест', $string);
var_dump($result); // Возможен false или искаженный результат
?>
Использование без включенного модуля mbstring

Вызов функции без установленного модуля mbstring вызовет фатальную ошибку.

Синтаксис регулярных выражений

mb_eregi использует синтаксис регулярных выражений POSIX, который отличается от синтаксиса PCRE (используемого в preg_match). Например, для обозначения границы слова в POSIX используется [[:<:]] и [[:>:]].

<?php
$string = 'слово тест слово';
// Неправильно для POSIX (это синтаксис PCRE):
$result = mb_eregi('\bтест\b', $string, $matches);
var_dump($result); // bool(false)
// Правильно для POSIX:
$result = mb_eregi('[[:<:]]тест[[:>:]]', $string, $matches);
var_dump($result, $matches);
?>
bool(false)
bool(true)
array(1) {
  [0]=>
  string(8) "тест"
}

Изменения в последних версиях PHP

PHP 7.3

Объявлена устаревшей (deprecated) функция mb_eregi, как и другие функции семейства ereg в модуле mbstring. Разработчикам рекомендуется переходить на использование функций PCRE (preg_match с модификатором i и u).

PHP 8.0

Вызов устаревших функций ereg из модуля mbstring по-прежнему возможен, но генерирует предупреждение об устаревании (E_DEPRECATED). Их планируется удалить в будущих основных версиях PHP.

Расширенные примеры

Поиск нескольких вхождений

Функция mb_eregi находит только первое вхождение. Для поиска всех вхождений необходимо использовать цикл с mb_ereg_search.

Пример php
<?php
mb_internal_encoding('UTF-8');
$string = 'Один два три два один';
$pattern = 'два';
$offset = 0;
$all_matches = [];
while (mb_eregi($pattern, $string, $matches, $offset)) {
    $all_matches[] = $matches[0];
    $pos = mb_strpos(mb_strtolower($string), mb_strtolower($matches[0]), $offset);
    $offset = $pos + mb_strlen($matches[0]);
}
print_r($all_matches);
?>
Array
(
    [0] => два
    [1] => два
)
Извлечение данных из структурированного текста
Пример php
<?php
$data = "Имя: Алексей\nФамилия: Сидоров\nГород: Москва";
mb_eregi('Имя:\s*([^\n]+)', $data, $name_match);
mb_eregi('Фамилия:\s*([^\n]+)', $data, $surname_match);
mb_eregi('Город:\s*([^\n]+)', $data, $city_match);

$person = [
    'name' => $name_match[1] ?? null,
    'surname' => $surname_match[1] ?? null,
    'city' => $city_match[1] ?? null
];
print_r($person);
?>
Array
(
    [name] => Алексей
    [surname] => Сидоров
    [city] => Москва
)
Валидация кириллического имени
Пример php
<?php
function isValidCyrillicName($name) {
    // Соответствует кириллическим буквам, дефису и пробелу
    return mb_eregi('^[А-ЯЁа-яё\-\s]+$', $name) === 1;
}

$names = ['Анна', 'Мария-Луиза', 'Иван Петров', 'John123'];
foreach ($names as $name) {
    echo $name . ': ' . (isValidCyrillicName($name) ? 'Да' : 'Нет') . "\n";
}
?>
Анна: Да
Мария-Луиза: Да
Иван Петров: Да
John123: Нет
Замена с использованием mb_eregi_replace

Несмотря на то что вопрос о mb_eregi, стоит показать связанную функцию замены.

Пример php
<?php
$text = 'цвет и колор';
// Заменяем оба варианта написания на 'color'
$newText = mb_eregi_replace('(цв[еэ]т|колор)', 'color', $text);
echo $newText;
?>
color и color

Аналоги в других языках

Python

Для регистронезависимого поиска с поддержкой Unicode используется флаг re.IGNORECASE (re.I) модуля re.

import re
string = 'Привет, мир!'
match = re.search('мир', string, re.IGNORECASE | re.UNICODE)
print(match is not None)
if match:
    print(match.group(0))
True
мир

Mb eregi в Javascript

В JavaScript используется метод match() или RegExp с флагом i для регистронезависимого поиска. Для работы с Unicode лучше использовать флаг u.

const string = 'Привет, мир!';
const regex = /мир/ui;
const match = string.match(regex);
console.log(match !== null);
if (match) {
    console.log(match[0]);
}
true
мир

Mb eregi в MySQL

Оператор REGEXP или RLIKE по умолчанию регистрозависим в зависимости от коллации. Для регистронезависимого поиска в UTF-8 можно использовать коллацию, которая не чувствительна к регистру, например, utf8mb4_unicode_ci.

-- Предполагается, что коллация таблицы/столбца utf8mb4_unicode_ci
SELECT 'Привет, мир!' REGEXP 'МИР' as found;
found: 1

PHP mb_eregi function comments

En
Mb eregi Alias of mb_eregi