Доброго времени суток.
Собственно столкнулся с одной проблемой, самостоятельно решить которую не могу. Необходимо обрабатывать средствами PHP вводимый пользователями текст для передачи его поисковому движку Sphinx. Поиск производится по всем имеющимся словам, а не фразе. Для этого перед каждым отдельным словом добавляем оператор +.
Для данной цели использую следующую функцию:
function clean_text_match ($text, $all_words)
{
global $db, $bb_cfg;
$text = ' '. mb_strtolower($text, 'UTF-8') .' ';
if ($all_words)
{
$text = preg_replace('#\s(\b\w)#', ' +$1', $text);
}
$text_match_sql = $db->escape(trim($text));
return $text_match_sql;
}
Суть проблемы состоит в некорректной обработке поступающего текста регулярным выражением. Для примера возьмем, что пользователь искал фильм «Секс в большом городе». При поиске фразы «секс в большом городе», в эхе текста, обработанного функцией, видим, что он каким был — таким он и остался:
секс в большом городе
Вводим соответствующую фразу на английском языке и в результате имеем то, что и было задумано:
+sex +and +the +city
Как видите — русский текст через регулярное выражение по непонятной мне причине не проходит. С английским — все отлично. Все текстовые фразы на обработку поступают в уже нужной кодировке (UTF-8) и в принципе каких-либо проблем с самим текстом быть не должно. Следовательно, проблема в самом регулярном выражении.
Немного упрощаем его до вот такой конструкции:
...
if ($all_words)
{
$text = preg_replace('#\s#', ' +$1', $text);
}
...
Прогоняем русский текст:
+секс +в +большом +городе +
Вроде как все отлично (кроме последнего пробела также получившего +). Однако, если я захочу использовать другие операторы Sphinx, например оператор NOT (! или -), то в результате прогонки текста с таким отрицанием (отрицаем слово город) иметь будем следующее:
+секс +в +большом +-городе +
Что является неверным, т.к. в идеале мы в случае отрицания должны иметь следующий текст:
+секс +в +большом -городе
Поиски похожего регулярного выражения, которое сможет разбивать слова определенными символами, пропуская те, перед которыми уже есть не пробельный символ (@,!,- и т.д.) у меня успехом не увенчались. Поэтому и обращаюсь с просьбой о помощи сюда: есть ли способ осуществить задуманное с иным регулярным выражением?
Во время поисков наткнулся на вот такой комментарий:
ru2.php.net/manual/ru/regexp.reference.escape.php#102868 — судя по всему, управляющая последовательность \b просто не дружит с юникодом.
Спасибо.