Здравствуйте!
Возникла следующая проблема.
Необходимо в строке выделить жирным определенный текст (как в результатах поиска).
Например, было: "Просто какой-то текст", надо выделить "Какой", то есть получить: "Просто какой-то текст" (при чем, как видно, регистр не имеет значения)
Пробовал это делать регулярными выражениями, разными функциями, при чем использовал разные кодировки текста (и windows-1251, и utf-8), но ничего не получается..
При чем еще такая особенность: до выполнения drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
всё работает, а после - резко не хочет..
Добавлено:
Гм.. Сейчас вот попробовал упорядоченно испытать все возможные комбинации функций и кодировок.
И получилось следующее..
Примечание
Исходный код в кодировке windows-1251, для конвертации в utf-8 используется функция
function w($value) { return iconv("windows-1251", "utf-8", $value); }
Отображение идет в кодировке utf-8
index.php
До и после выполнения drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
вставлялся следующий код:
echo w(preg_replace(('/(Какой)/'), "(\\1)", ('Просто какой-то текст'))."<br/>");
echo preg_replace(w('/(Какой)/i'), "(\\1)", w('Просто какой-то текст'))."<br/>";
echo w(preg_replace(('/(Какой)/i'), "(\\1)", ('Просто какой-то текст'))."<br/>");
echo ereg_replace(w('(Какой)'), "(\\1)", w('Просто какой-то текст'))."<br/>";
echo w(ereg_replace(('(Какой)'), "(\\1)", ('Просто какой-то текст'))."<br/>");
echo eregi_replace(w('(Какой)'), "(\\1)", w('Просто какой-то текст'))."<br/>";
echo w(eregi_replace(('(Какой)'), "(\\1)", ('Просто какой-то текст'))."<br/>");
echo mb_ereg_replace(w('(Какой)'), "(\\1)", w('Просто какой-то текст'))."<br/>";
echo w(mb_ereg_replace(('(Какой)'), "(\\1)", ('Просто какой-то текст'))."<br/>");
echo mb_eregi_replace(w('(Какой)'), "(\\1)", w('Просто какой-то текст'))."<br/>";
echo w(mb_eregi_replace(('(Какой)'), "(\\1)", ('Просто какой-то текст'))."<br/>");
При этом до выполнения drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
выполнились успешно строки:
echo w(eregi_replace(('(Какой)'), "(\\1)", ('Просто какой-то текст'))."<br/>");
echo w(mb_eregi_replace(('(Какой)'), "(\\1)", ('Просто какой-то текст'))."<br/>");
А после выполнения drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
только одна:
Вывод:
Чтобы решить проблему, работать нужно ТОЛЬКО со строками в кодировке windows-1251 (а не utf-8).
То есть, если строки всё-таки в кодировке utf-8, то нужно временно перевести их в windows-1251
При чем чтобы всё заработало в Друпал, необходимо с этими windows-1251 строками работать ТОЛЬКО с помощью функций mb_eregi_replace.
Вот такие странные у меня получились выводы.
Пожалуйста, поправьте меня, если я в чем-то не прав или если существуют еще пути решения этой проблемы..
Комментарии
Стоит помнить, что регулярные выражения Perl (функции preg*) и POSIX (функции ereg*) отличаются синтаксисом. Например для preg* нужно в конце выражения ставить модификатор i:
Остальные модификаторы - http://ru2.php.net/manual/ru/reference.pcre.pattern.modifiers.php
Также следует помнить, что только ereg-функции имеют дубли в mbstring, а preg-функции - не имеют. Вместо этого в Perl-регвырах можно использовать модификатор u указывающий на необходимость работы с юникодом.
А можно посмотреть пример задачи для которой пришлось так извращаться?
Задача самая банальная.
Производится поиск в БД, результат выдается в виде строк-ссылок. Нужно в этих найденных стоках подсветить искомое слово.
Например, искали слово "книга". Результат нужно отобразить в виде:
axel, большое спасибо за быстрый ответ!
Отличия ereg и preg я учел, модификатор i для preg ставил, mb-функции для ereg пробовал.
А вот про модификатор u не догадался
И это получается еще один рабочий вариант:
То есть работать можно с текстом в кодировке utf-8 и всё работает замечательно!
Еще раз спасибо!
Вот такая функция получилась с помощью preg_replace, w() убрал т.к. уже не нужен этот вызов:
if (!empty($searchItem) && !empty($text)) {
return preg_replace('/('.$searchItem.')/iu',
"<span class='highlight'>".$searchItem."</span>", $text);
}
else {
return $text;
}
}
Теперь другая проблемка, в $text найденное заменяется на $searchItem с учетом регистра, а вот как сделать, чтобы регистр оставался таким же, какой он в $text, то есть:
highlight('тЕст', 'Тут тестовый текст');
на выходе: Тут тЕстовый текст, а нужно чтобы регистр оставался тем же...
Не критичная проблемка, но всё таки...
Решение - использовать карманы, то есть вместо
<?php
return preg_replace('/('.$searchItem.')/iu',
"<span class='highlight'>".$searchItem."</span>", $text);
?>
написать
<?php
return preg_replace('/('.$searchItem.')/iu',
"<span class='highlight'>$1</span>", $text);
?>