форум общения русскоязычных пользователей CMS Текстпаттерн
Вы не зашли.
Если искомое слово написано латинецей, то какими буквами оно написано не важно, заглавные или прописные - все ищется. А в случае с кирилицей, то приходится писать буквально как в исходном тексте - фамилии с заглавной и тд. иначе ничего не будет найдено. Если у кого есть опыт решения проблемы, поделитесь...
Кстати: может кому полезно будет мой опыт решения задачи: "заставить" работать поиск в случае когда вывод новостей на первой стр. оганизован за счет применения тэга txp:article_custom (была необходимость выводить новости в обратном порядке и с заданной новости и тэг <txp:article /> неприемлем был, а именно с ним в паре работает тэг поиска <txp:search_input />). Задача решилась использованием <txp:article limit=1,2 /> то есть включение limit=1,2 в данный тэг не позволило выводить статьи, так как txp:article не понимет условие limit=1,2 но результаты поиска начали выводиться в том месте где записано <txp:article limit=1,2 />
Неактивен
leon написал:
Задача решилась использованием <txp:article limit=1,2 /> то есть включение limit=1,2 в данный тэг не позволило выводить статьи, так как txp:article не понимет условие limit=1,2 но результаты поиска начали выводиться в том месте где записано <txp:article limit=1,2 />
на главном форуме пишут про неработающий limit=1,2:
please ignore that.
for anyone else wondering: attribute offset=”x” replaces limit=”x,y” attribute since revision 385.
Неактивен
прим. Администратора
Осуществлен сюда перенос сообщений из другой темы
kislitsyn написал:
А независимый от регистра поиск появился? :-)
Неактивен
Evgeny написал:
kislitsyn написал:
А независимый от регистра поиск появился? :-)
Ирония неуместна, хотя и понятна :-))
Нет, к сожалению, регистр букв при поиске в русском языке, по прежнему не учитывается :-((
Это связано с некорректной работой строковых функций в php c utf-8.
Некоторое время назад Martian написал мне, что эту проблему решить можно, но это - непросто. В том смысле, что не одну-две строчки в коде переделать.
Так как регулярно идут обновления версий (видимо 4.0.2 уже не за горами), как-то неловко возвращаться к тому разговору, поддерживать большой блок изменений в условиях постояных обновлений версий крайне тяжело. К тому же, там могут еще и глюки дополнительные вылезти. Поэтому эта тема отложена до лучших времен.
Тем не менее, поиск, что присутствует сейчас, пусть и неполноценный, в некоторых случаях может быть полезен и его нельзя уж совсем сбрасывать со счетов.
Неактивен
Martian написал:
День добрый.
Там проблема собственно, как я понял, в не совсем корректном создании и работе с базой в utf8.
Можно легко сделать работающим регистронезависимый поиск, если _перед_! установкой добавить пару строчек, а именно:
1:
textpattern/lib/txplib_db.ph
В function DB()
после 18 строки
} else $GLOBALS['connected'] = true;
добавляем
mysql_query("SET NAMES utf8");
2:
textpattern/setup.php
В function printConfig() после строк:
echo graf('Connected.');
if (!$mydb = mysql_select_db($ddb)) {
exit(graf("Database ".strong($ddb)." doesn't exist. Please create it or choose another."))
}
Это 115-117 строки файла, тоже вставляем
mysql_query("SET NAMES utf8");
И уже после изменений запускать сетап и создавать базу.
Номера строк могут не соответствовать, у меня версия не сильно свежая. Но идея, надеюсь, понятна.
На уже работающем сайте это не поможет (во всяком случае не помогает в моей конфигурации). И как корректно сконвертировать данные я пока не знаю
Добавление:
Возможно нужно будет добавить
default-character-set=cp1251
В секцию [mysql] конфигурационного файла MySQL - my.cnf
Неактивен
Nicck написал:
Martian написал:
Можно легко сделать работающим регистронезависимый поиск, если _перед_! установкой добавить пару строчек, а именно:
1:
textpattern/lib/txplib_db.ph
В function DB()
после 18 строки
} else $GLOBALS['connected'] = true;
добавляем
mysql_query("SET NAMES utf8");В txp 4.0.1 "SET NAMES utf8" уже делается, об этом я как-то уже упоминал, но не в связи с поиском.
textpattern/lib/txplib_db.php:36Код:
if ( isset($txpcfg['dbcharset']) && (intval($version[0]) >= 5 || preg_match('#^4\.[1-9]#',$version)) ) mysql_query("SET NAMES ". $txpcfg['dbcharset']);Martian написал:
2:
textpattern/setup.php
В function printConfig() после строк:
echo graf('Connected.');
if (!$mydb = mysql_select_db($ddb)) {
exit(graf("Database ".strong($ddb)." doesn't exist. Please create it or choose another."))
}
Это 115-117 строки файла, тоже вставляем
mysql_query("SET NAMES utf8");
И уже после изменений запускать сетап и создавать базу.
Номера строк могут не соответствовать, у меня версия не сильно свежая. Но идея, надеюсь, понятна.textpattern/setup/index.php:201
Код:
// On 4.1 or greater use utf8-tables $version = mysql_get_server_info(); if ( intval($version[0]) >= 5 || preg_match('#^4\.[1-9]#',$version)) { if (mysql_query("SET NAMES utf8")) { $carry['dbcharset'] = "utf8"; $carry['dbcollate'] = "utf8_general_ci"; } else $carry['dbcharset'] = "latin1"; } else $carry['dbcharset'] = "latin1";для mysql4+ как видишь выполняется всё что надо.
Опиши в чём собственно проблема, почему не ищется, и где мне об этом почитать. Голое рещение конечно хорошо, но данных недостаточно чтоб начать чувствовать, что решение близко и начать его искать.
Неактивен
Beginner написал:
вот тут толкуют, что в mysql 4.1 это проблема будет решена
P.S. Вот еще ссылка по теме
Неактивен
Я сам (глубоко не вдаваясь в силу отсутствия спец.знаний) полагал, что проблема содержится в функциях обработки строк (типа strtolower и т.п.), судя по разговорам на форуме, в этом заблуждении был не только я. Но сейчас разговор перешел в иную плоскость, все взоры устремились на работу mysql с utf-8.
Посвоевольничал я немного, решил воспользоваться паролем, который когда-то любезно :-)) дал Yurik и задал этот вопрос в livejournal в ru_mysql. Тех, для кого эта проблема с регистрозависимым поиском еще интересует, могут ознакомиться с предложениями специалистов по mysql здесь.
Отредактированно Evgeny (03-10-2005 18:24:50)
Неактивен
Evgeny написал:
решил воспользоваться паролем
для хорошего дела ничего не жалко
посмотрел на развитие упомянутой библиотеки PCRE http://sourceforge.net/project/showfile … p_id=10194 , действительно изменений много. полистал changelog на http://www.pcre.org/ , понял мало, но изменений по работе с utf8 много.
Отредактированно Yurik (04-10-2005 12:52:07)
Неактивен
любопытно эту версию проверить.
у меня на одном хостинге эта библиотека от 2002 года, на другом - 2003,
у знакомых на мастерхосте - ппх обрезанный, phpinfo() не работает.
еще у одних знакомых тоже 2003 года :-((
У кого-нибудь есть хостинг с более свежей библиотекой PCRE?
Неактивен
у меня тоже 2003 года ![]()
Неактивен
Вобщем надоело мне ждать и я решил решить проблему. И решил.
Итак, есть 2 проблемы:
1) При запросе к базе регистр учитывается.
Решение:
в tetpattern/publish.php (r884 из релиза 4.0.1) меняем
строку 516:
$search = " and (Title rlike '$q' or Body rlike '$q') $s_filter";
на:
$search = " and (upper(Title) rlike upper('$q') or upper(Body) rlike upper('$q')) $s_filter";2) При выводе результата, в момент когда искомая строка должны быть подсвечена полужирным, при обработке регулярного выражения регистр опять не учитывается, не смотря на модификатор i
Решение:
в textpattern/publish/taghandlers.php (r887 из релиза 4.0.1)
в функции search_result_excerpt
добавляем (например перед строкой extract($thisarticle)
следующее:
!!! исходник нужно сохранять в кодировке utf-8 !!!
if ( !is_callable("get_down") ) { // utf-8 cyr. to lowercase
function get_down($str)
{
$dw = explode(" ", "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я");
$up = explode(" ", "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я");
return str_replace($up, $dw, $str);
}
}Ниже, строку:
preg_match_all("/\s.{1,50}".preg_quote($q).".{1,50}\s/iu",$result,$concat);заменить на:
preg_match_all("/\s.{1,50}".preg_quote(get_down($q)).".{1,50}\s/u",get_down($result),$concat);и еще ниже:
$concat = preg_replace("/(".preg_quote($q).")/i","<$hilight>$1</$hilight>",$concat);заменить на:
$concat = preg_replace("/(".preg_quote(get_down($q)).")/i","<$hilight>$1</$hilight>",$concat);Если знаете что такое diff и patch то вот файлы:
publish.php.patch
516c516
< $search = " and (Title rlike '$q' or Body rlike '$q') $s_filter";
---
> $search = " and (upper(Title) rlike upper('$q') or upper(Body) rlike upper('$q')) $s_filter";taghandlers.php.patch !!! Сохранять в utf-8 !!!
1070a1071,1079
> if ( !is_callable("get_down") ) { // utf-8 cyr. to lowercase
> function get_down($str)
> {
> $dw = explode(" ", "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я");
> $up = explode(" ", "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я");
> return str_replace($up, $dw, $str);
> }
> }
>
1074c1083
< preg_match_all("/\s.{1,50}".preg_quote($q).".{1,50}\s/iu",$result,$concat);
---
> preg_match_all("/\s.{1,50}".preg_quote(get_down($q)).".{1,50}\s/u",get_down($result),$concat);
1080c1089
< $concat = preg_replace("/(".preg_quote($q).")/i","<$hilight>$1</$hilight>",$concat);
---
> $concat = preg_replace("/(".preg_quote(get_down($q)).")/i","<$hilight>$1</$hilight>",$concat);Справедливы для файлов из релиза 4.0.1(r888)
$HeadURL: http://svn.textpattern.com/development/ … ublish.php $
$LastChangedRevision: 884 $
$HeadURL: http://svn.textpattern.com/development/ … ndlers.php $
$LastChangedRevision: 887 $
Думаю этого достаточно.
--
Есть конечно недостаток у этого метода, результаты поиска выводятся в нижнем регистре.
Я впринципе уже почти переписал функцию search_result_excerpt(), но возникла небольшая проблемка. Если руки дойдут... ну как обычно вобщем. Есои сильно надо, говорите, может и допишу. Если этот вариант устраивает то ещё лучше. Я лично и этим доволен.
Отредактированно Nicck (11-10-2005 20:57:26)
Неактивен
Nicck написал:
Если знаете что такое diff и patch то вот файлы:
а что такое diff и patch?
Неактивен
Nicck написал:
Есои сильно надо, говорите, может и допишу.
НАДО!!! Я думаю все будут премного благодарны.
И нужно бы ещё как-то связаться с Dean'ом или другими разработчиками и окончательно решить эту проблему в следующих релизах...
Неактивен
Denny написал:
НАДО!!! Я думаю все будут премного благодарны.
Дописал. Вот новая функция:
(ниже по тексту есть ссылки на уже поправленные файлы)
// -------------------------------------------------------------
function search_result_excerpt($atts)
{
global $thisarticle, $q;
extract(lAtts(array(
'hilight' => 'strong',
),$atts));
if (empty($thisarticle)) return;
extract($thisarticle);
$result = strip_tags(preg_replace("/>\s*</","> <",$body));
// UTF-8 //
$up = explode(" ", "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я");
$dw = explode(" ", "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я");
$res_up = str_replace($up, $dw, $result); // to lowercase
$q_up = str_replace($up, $dw, $q); // to lowercase
$res_len = strlen($res_up);
$q_len = strlen($q_up);
// найдём позиции искомой строки в тексте (уже без тэгов)
$pos = array();
for ($i=0; $i < strlen($res_up); $i++) if (substr($res_up,$i,$q_len) == $q_up) $pos[] = $i;
// выделим интервалы которые мы будем выводить: \s<-- ~40 символов -->слово<-- ~40 символов -->\s
// вобще 40 это для кирилицы, на латиницу бедет по 80 примерно. utf-8 однако.
$pos = array_chunk($pos,1);
for ($i=0; $i < sizeof($pos); $i++)
{
$rt = $pos[$i][0] + 80 + $q_len;
$lt = $pos[$i][0] - 80;
if ($lt < 0) $lt = 0;
if ($rt > $res_len) $rt = $res_len;
while ($res_up{$lt}!=" " and $lt>0) $lt--;
while ($res_up{$rt}!=" " and $rt<$res_len) $rt++;
$pos[$i][1] = $lt;
$pos[$i][2] = $rt;
}
// теперь Array ( Array ( 0 => позиция слова,
// 1 => начало интервала,
// 2 => конец интервала ), ... )
// если интервалы пересекаются:
// | ~40 предыдущий ~0..80 | текущий ~40 |
// <-- перед словом -->слово<-- между словами -->слово<-- после слова -->
for ($i=1; $i < sizeof($pos); $i++)
if ($pos[$i][1] <= $pos[$i-1][2])
{
$pos[$i][1] = $pos[$i][0];
$pos[$i-1][2] = $pos[$i][0];
}
foreach($pos as $val)
{
if ($val[0] != $val[1]) $ret .= " ... ";
$ret .= substr($result, $val[1], $val[0]-$val[1]);
$ret .= "<$hilight>" . substr($result, $val[0], $q_len) . "</$hilight>";
$ret .= substr($result, $val[0]+$q_len, $val[2]-$val[0]-$q_len);
}
return $ret .= $ret ? " ..." : '';
}
// -------------------------------------------------------------Необходимость править publish.php остаётся. Об этом вчера писал.
!!! taghandlers.php должен быть в utf-8
Если у вас нет текстового редактора
то вот вам:
nck_search_mod.zip
уже готовые поправленные файлы, вам остаётся только заменить свои старые на них.
taghandlers.php там кстати, не тот, что был в поставке 4.0.1 когда я её качал,чуть посвежее, что-то там пофиксили.
Denny написал:
И нужно бы ещё как-то связаться с Dean'ом или другими разработчиками и окончательно решить эту проблему в следующих релизах...
Моё решение не универсально, т.е. правка publish.php конечно приводит к тому, что поиск в базе начинает работать, но вот новая функция search_result_excerpt() реализует подсветку только для кирилицы.
Вчерашний вариант кстати должен подойти всем, но у него есть недостаток (результаты поиска выводятся в нижнем регистре).
upd: это я погорячился, не подойдёт он тоже.
Отредактированно Nicck (13-10-2005 18:02:00)
Неактивен
Супер, в копилку.
Неактивен
То что решение есть, это отлично!
Не надо забывать, что это - хак, со всеми связанными с этим проблемами по поддержке хака от версии к версии.
Может быть можно оформить его таким образом, чтобы менялась одна-две строчки в "родном" коде?
Неактивен
Меняется *одна строчка* в publish.php
и *одна функция* в taghandlers.php
Не вижу никаких проблем и нужды ещё что-то придумывать. Всё и так максимально просто.
Неактивен
в принципе- да. тут дело уже личных предпочтений.
Неактивен
Есть ещё одна проблема: буквы «е» и «ё» считаются разными. Если в тексте в слове Ё, в ищется слово с буквой Е - то не найдёт. Как обойти подобное?
Неактивен
Дорабатываем решение:
1. Изменённая строка для publish.php
$search = " and (replace(upper(Title),'Ё','Е') rlike replace(upper('$q'),'Ё','Е') or replace(upper(Body),'Ё','Е') rlike replace(upper('$q'),'Ё','Е')) $s_filter";2. Изменённые строки в функции search_result_excerpt файла taghandlers.php
$up = explode(" ", "А Б В Г Д Е Ё ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я");
$dw = explode(" ", "а б в г д е е е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я");Неактивен