Mb ereg search setpos: примеры (PHP)

Использование функции mb_ereg_search_setpos для работы с многобайтовыми строками
Раздел: Многобайтовые строки
mb_ereg_search_setpos(int $offset): bool

Функция mb_ereg_search_setpos

Функция mb_ereg_search_setpos устанавливает начальную позицию для выполнения поиска с использованием многобайтовых регулярных выражений. Эта функция применяется в комбинации с mb_ereg_search_init и mb_ereg_search для итеративного поиска в строке.

Когда используется

Использование функции актуально при необходимости последовательного поиска всех вхождений шаблона в строке, особенно когда работа ведется с многобайтовыми кодировками, такими как UTF-8. Это позволяет перемещаться по строке и находить соответствия, начиная с заданной позиции.

Аргументы функции
  • position (обязательный): Целое число, определяющее позицию в байтах, с которой начнется следующий поиск. Нумерация начинается с 0.
  • encoding (необязательный): Кодировка строки. Если не указана, используется внутренняя кодировка.

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

Простой пример

Установка позиции для поиска:

mb_regex_encoding('UTF-8');
$string = 'Пример строки для теста';
$pattern = '[а-я]+';

mb_ereg_search_init($string, $pattern);

// Установка начальной позиции в 7 байт (примерно после 'Пример ')
mb_ereg_search_setpos(7);

while ($matches = mb_ereg_search()) {
    $result = mb_ereg_search_getregs();
    print_r($result);
}
Array
(
    [0] => строки
)
Array
(
    [0] => для
)
Array
(
    [0] => теста
)
Пример с указанием кодировки
$string = '東京と京都';
$pattern = '.+';
mb_ereg_search_init($string, $pattern, 'UTF-8');
mb_ereg_search_setpos(3, 'UTF-8'); // Пропуск первого символа (3 байта в UTF-8)

if ($matches = mb_ereg_search()) {
    print_r(mb_ereg_search_getregs());
}
Array
(
    [0] => 京と京都
)

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

preg_match_all

Функция preg_match_all выполняет глобальный поиск шаблона в строке, возвращая все совпадения. Не требует установки позиции итеративно. Предпочтительна для однократного поиска всех вхождений.

mb_ereg_search_regs

Функция mb_ereg_search_regs возвращает результат последнего совпадения многобайтового регулярного выражения. Часто используется вместе с mb_ereg_search_setpos для управления позицией поиска.

Рекомендации

Использование mb_ereg_search_setpos оправдано при необходимости тонкого контроля за позицией поиска в многобайтовых строках. Для большинства задач подходит preg_match_all с модификатором u для UTF-8.

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

Установка позиции за пределами строки

Если позиция превышает длину строки, поиск не дает результатов.

mb_regex_encoding('UTF-8');
$string = 'Тест';
$pattern = '.';
mb_ereg_search_init($string, $pattern);
mb_ereg_search_setpos(10); // Позиция вне строки

var_dump(mb_ereg_search());
bool(false)
Неправильная кодировка

Указание неверной кодировки приводит к некорректному подсчету байтов и ошибочным результатам.

$string = 'Кафе';
$pattern = '.';
mb_ereg_search_init($string, $pattern, 'UTF-8');
mb_ereg_search_setpos(2, 'CP1251'); // Несоответствие кодировок

while ($matches = mb_ereg_search()) {
    print_r(mb_ereg_search_getregs());
}
// Результат непредсказуем, возможны ошибки

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

В PHP 8.0 функция mb_ereg_search_setpos теперь выбрасывает исключение ValueError, если параметр position меньше 0. Ранее в таких случаях возвращалось false.

// PHP 8+
try {
    mb_ereg_search_setpos(-1);
} catch (ValueError $e) {
    echo $e->getMessage();
}
mb_ereg_search_setpos(): Argument #1 ($position) must be greater than or equal to 0

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

Поиск с пропуском части строки

Игнорирование первых N символов при поиске.

Пример php
function searchFromPosition($string, $pattern, $startPos) {
    mb_regex_encoding('UTF-8');
    mb_ereg_search_init($string, $pattern);
    mb_ereg_search_setpos($startPos);
    
    $results = [];
    while ($matches = mb_ereg_search()) {
        $regs = mb_ereg_search_getregs();
        $results[] = $regs[0];
    }
    return $results;
}

$text = 'Яблоко, груша, слива, апельсин';
$found = searchFromPosition($text, '[а-я]+', 8);
print_r($found);
Array
(
    [0] => груша
    [1] => слива
    [2] => апельсин
)
Обработка текста с смещением

Поиск всех email адресов, начиная с определенной позиции.

Пример php
$text = 'Контакты: test@example.com, admin@site.ru. Резерв: info@domain.com';
mb_ereg_search_init($text, '[\w\d._%+-]+@[\w\d.-]+\.[a-z]{2,}');
mb_ereg_search_setpos(20); // Пропуск 'Контакты: test@example.com, '

$emails = [];
while (mb_ereg_search()) {
    $emails[] = mb_ereg_search_getregs()[0];
}
print_r($emails);
Array
(
    [0] => admin@site.ru
    [1] => info@domain.com
)
Комбинирование с mb_ereg_search_pos

Получение позиций найденных совпадений после установки начальной точки.

Пример php
$string = 'один два три четыре пять';
$pattern = '[а-я]+';
mb_ereg_search_init($string, $pattern);
mb_ereg_search_setpos(5); // Начать после 'один '

while (mb_ereg_search()) {
    $pos = mb_ereg_search_getpos();
    $regs = mb_ereg_search_getregs();
    echo "Слово '{$regs[0]}' начинается с позиции: $pos\n";
}
Слово 'два' начинается с позиции: 5
Слово 'три' начинается с позиции: 9
Слово 'четыре' начинается с позиции: 13
Слово 'пять' начинается с позиции: 20

Альтернативы в других языках

Python

В Python аналогом является использование метода start у объекта совпадения (match object) и установка позиции в функции search через параметр pos.

import re
string = 'Пример строки'
pattern = re.compile(r'[а-я]+')
match = pattern.search(string, pos=7)  # Установка начальной позиции
if match:
    print(match.group())
строки
JavaScript

В JavaScript используется свойство lastIndex у регулярного выражения с флагом g для установки позиции поиска.

const string = 'Пример строки';
const pattern = /[а-я]+/g;
pattern.lastIndex = 7; // Установка позиции
const result = pattern.exec(string);
console.log(result[0]);
строки
MySQL

В MySQL функция REGEXP_INSTR возвращает позицию совпадения, но не позволяет явно устанавливать начальную позицию поиска. Альтернативой является использование подстроки с смещением.

PHP mb_ereg_search_setpos function comments

En
Mb ereg search setpos Set start point of next regular expression match