форум общения русскоязычных пользователей 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(" ", "а б в г д е е е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я");
Неактивен