PHP regexp UTF-8

Данная запись выбивается из общего потока так или иначе связанных с электроникой материалов.  Но я предупреждал — материалы на сайте будут самые разные, т.к. в первую очередь здесь та информация которую я хотел сохранить для себя.

Занимаясь также и программированием, столкнулся с задачей обработки текстов в UTF-8 формате при помощи регулярных выражений, используя PHP. Столкнулся с тем что документация по этой теме какая-то неполная и умалчивающая некоторые вещи, а интернет полон перепечатанных друг у друга статей, не особо раскрывающих тему.   Кое до чего пришлось докопаться самому, кое какие подтверждения своим экспериментам нашел нашел таки в англоязычном блоге, статью из которого в довольно свободном переводе привожу здесь.   Повторяю — перевод довольно вольный, возможны неточности, ссылка на оригинальную статью в конце заметки.

Итак, перевод:

PHP водержит некоторые семейства функций, не особо известных широкой аудитории  (и я бы сказал «кривовато» документированных).  Одно из таких семейств — функции вида mb_ereg_*.

Общепринятое заблуждение (прим. моё: я не проверял данные факты, просто привожу перевод оригинальной статьи) — функции mb_ereg_* это «юникодные» надстройки, аналоги функций ereg_*,  притом медленные и маломощные.  Это так далеко от истины, как только может быть.

mb_ereg_* функции базированы на библиотеке обработки регулярных выражений  oniguruma,  которая есть одна из самых скоростных и наиболее обеспечивающих совместимость библиотек обработки регулярных выражений.

Однако, сейчас немного поговорим о их использовании — документация по PHP весьма скудно описывает эти функции.

Начнем с базового факта: при использовании mb_ereg_* функций регулярное віражение не нужно обрамлять «делимиттерами» !  (обычно используют «/» —  действительно об этом нигде не написано 🙁  Экспериментально я нашел этот факт, но удивлялся почему это так — ведь в обычных агалогах функций работы с регулярными выражениями оно всегда берется в ограничители, даже есть куча нюансов в их использовании.)

Пример:
<?php
// find first substring consisting of letters from 'a' to 'c' in 'abcdabc' string.
mb_ereg('[a-c]+', 'abcdabc', $res);

?>

Чтобы выполнить тот же поиск, только регистронезависимый — используйте mb_eregi();

Функции mb_ereg(), mb_eregi(), mb_slpit() используют предустановленные опции при работе.  Опции можно посмотреть/установить используя функцию mb_regex_set_options().

Функция принимает строковые параметры, каждая буква которых обозачает что-то.

Используемые параметры (можно использовать несколько одновременно):

  • ‘i’: ONIG_OPTION_IGNORECASE
  • ‘x’: ONIG_OPTION_EXTEND
  • ‘m’: ONIG_OPTION_MULTILINE
  • ’s’: ONIG_OPTION_SINGLELINE
  • ‘p’: ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE
  • ‘l’: ONIG_OPTION_FIND_LONGEST
  • ‘n’: ONIG_OPTION_FIND_NOT_EMPTY
  • ‘e’: eval() resulting code

Используемые «режимы» (если указать несколько из них — использоваться будет последний):

  • ‘j’: ONIG_SYNTAX_JAVA
  • ‘u’: ONIG_SYNTAX_GNU_REGEX
  • ‘g’: ONIG_SYNTAX_GREP
  • ‘c’: ONIG_SYNTAX_EMACS
  • ‘r’: ONIG_SYNTAX_RUBY
  • ‘z’: ONIG_SYNTAX_PERL
  • ‘b’: ONIG_SYNTAX_POSIX_BASIC
  • ‘d’: ONIG_SYNTAX_POSIX_EXTENDED

Например, mb_regex_set_options(‘pr’) эквивалетнто mb_regex_set_options(‘msr’) и обозначает:

  1. метасимвол . включает \n  — так называемый «мультистрочный поиск»
  2. ^ эквивалентно \A,  ; эквивалентно \Z  (строки считаются одной строкой)
  3. используется «RUBY» режим.

Кстати, это настройки «по умолчанию» функций mb_ereg_* .   И функции могут принимать опции/параметры непосредственно.

Итак, вернемся к функциям:

<?php // make sure, that the whole string matches the regexp:

mb_ereg_match(‘[a-c]+’, $user_string, ‘pz’);

‘pz’ указывает сто в данном случае исмользуется «перловский» стиль мультистрочных строк.

 

 

Заменить любую из буков в диапазоде от ‘a’ до  ‘c’  на ‘Z’:

$output = mb_ereg_replace(‘[a-c]’, ‘Z’, $user_string, ‘b’); // используется ‘POSIX BASIC’ режим

 

Ок, эти примеры были похожи на привычное использование preg_* функций.   Но есть что-то более мощное, заключенное в функциях mb_ereg_search_* : идея состоит в том что oniguruma может выполнять предразбор (препарсинг) и кеширование  текста/рег. выражения во внутреннем буфере. Использование этого даёт значительный выигрыш в скорости.

mb_ereg_search_init($some_long_text); //  — препарсит текст

mb_ereg_search(‘[a-c]’); // выполням поиск

while ($r = mb_ereg_search_getregs()) {  получаем следующий результат и работаем с ним

}

mb_ereg_search(‘[d-e]’);  // выполняем другой поиск по тому же тексту

mb_ereg_search_init($some_other_text); // препарсим другой текст

mb_ereg_search(); //выполяем поиск используя предыдущее, уже предобработанное рег выражение.

 

Это наиболее скоростной из известных автору способов обработки больших текстов на php.

<конец перевода 🙂  >

Ссылка на оригинал статьи: ода mb_ereg функциям.

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *