Textpattern - на русском языке

форум общения русскоязычных пользователей CMS Текстпаттерн

Вы не зашли.

#1 23-05-2005 15:10:31

leon
веди
Откуда: Новосибирск
Зарегистрирован: 23-05-2005
Сообщений: 18

Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Если искомое слово написано латинецей, то какими буквами оно написано не важно, заглавные или прописные - все ищется. А в случае с кирилицей, то приходится писать буквально как в исходном тексте - фамилии с заглавной и тд. иначе ничего не будет найдено. Если у кого есть опыт решения проблемы, поделитесь...

Кстати: может кому полезно будет мой опыт решения задачи: "заставить" работать поиск  в случае  когда вывод новостей на первой стр. оганизован за счет применения тэга 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 />

Неактивен

 

#2 02-06-2005 10:08:19

Beginner
земля
Зарегистрирован: 22-04-2005
Сообщений: 104

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

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.

Неактивен

 

#3 03-10-2005 17:47:30

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

прим. Администратора
Осуществлен сюда перенос сообщений из другой темы

kislitsyn написал:

А независимый от регистра поиск появился? :-)

Неактивен

 

#4 03-10-2005 17:48:20

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Evgeny написал:

kislitsyn написал:

А независимый от регистра поиск появился? :-)

Ирония неуместна, хотя и понятна :-))

Нет, к сожалению, регистр букв при поиске в русском языке, по прежнему не учитывается :-((
Это связано с некорректной работой строковых функций в php c utf-8.

Некоторое время назад Martian написал мне, что эту проблему решить можно, но это - непросто. В том смысле, что не одну-две строчки в коде переделать.
Так как регулярно идут обновления версий (видимо 4.0.2 уже не за горами), как-то неловко возвращаться к тому разговору, поддерживать большой блок изменений в условиях постояных обновлений версий крайне тяжело. К тому же, там могут еще и глюки дополнительные вылезти. Поэтому эта тема отложена до лучших времен.

Тем не менее, поиск, что присутствует сейчас, пусть и неполноценный, в некоторых случаях может быть полезен и его нельзя уж совсем сбрасывать со счетов.

Неактивен

 

#5 03-10-2005 17:48:46

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Nicck написал:

Некоторое время назад Martian написал мне...

Хочется подробностей, опубликовал бы переписку с согласия автора.

Неактивен

 

#6 03-10-2005 17:49:16

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

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

Добавление:
Возможно нужно будет добавить
default-character-set=cp1251
В секцию [mysql] конфигурационного файла MySQL - my.cnf

Неактивен

 

#7 03-10-2005 17:50:00

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

glebotr написал:

Martian написал:

На уже работающем сайте это не поможет

Загадочно... Как так?

Неактивен

 

#8 03-10-2005 17:50:34

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

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+ как видишь выполняется всё что надо.

Опиши в чём собственно проблема, почему не ищется, и где мне об этом почитать. Голое рещение конечно хорошо, но данных недостаточно чтоб начать чувствовать, что решение близко и начать его искать.

Неактивен

 

#9 03-10-2005 17:51:10

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Beginner написал:

вот тут толкуют, что в mysql 4.1 это проблема будет решена

P.S. Вот еще ссылка по теме

Неактивен

 

#10 03-10-2005 17:51:30

Admin
земля
Зарегистрирован: 18-04-2005
Сообщений: 106
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Nicck написал:

Работаю на MySQL 4.1.8-max и поиск регистрозависим. Ссылки не помогли.

Неактивен

 

#11 03-10-2005 18:20:08

Evgeny
ять
Зарегистрирован: 15-03-2005
Сообщений: 1869

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Я сам (глубоко не вдаваясь в силу отсутствия спец.знаний) полагал, что проблема содержится в функциях обработки строк (типа strtolower и т.п.), судя по разговорам на форуме, в этом заблуждении был не только я. Но сейчас разговор перешел в иную плоскость, все взоры устремились на работу mysql с utf-8.

Посвоевольничал я немного, решил воспользоваться паролем, который когда-то любезно :-)) дал Yurik и задал этот вопрос в  livejournal в ru_mysql. Тех, для кого эта проблема с регистрозависимым поиском еще интересует, могут ознакомиться с предложениями специалистов по mysql здесь.

Отредактированно Evgeny (03-10-2005 18:24:50)

Неактивен

 

#12 04-10-2005 12:22:44

Yurik
земля
Зарегистрирован: 22-04-2005
Сообщений: 115

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Evgeny написал:

решил воспользоваться паролем

smile для хорошего дела ничего не жалко
посмотрел на развитие упомянутой библиотеки PCRE  http://sourceforge.net/project/showfile … p_id=10194 , действительно изменений много. полистал changelog на http://www.pcre.org/ , понял мало, но изменений по работе с utf8 много.

Отредактированно Yurik (04-10-2005 12:52:07)

Неактивен

 

#13 05-10-2005 17:06:37

Evgeny
ять
Зарегистрирован: 15-03-2005
Сообщений: 1869

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

любопытно эту версию проверить.
у меня на одном хостинге  эта библиотека от 2002 года, на другом - 2003,
у знакомых на мастерхосте - ппх обрезанный, phpinfo() не работает.
еще у одних знакомых  тоже 2003 года :-((

У кого-нибудь есть хостинг с более свежей библиотекой PCRE?

Неактивен

 

#14 06-10-2005 10:08:17

Beginner
земля
Зарегистрирован: 22-04-2005
Сообщений: 104

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

у меня тоже 2003 года sad

Неактивен

 

#15 11-10-2005 20:54:55

Nicck
ферт
Откуда: Ижевск
Зарегистрирован: 11-05-2005
Сообщений: 536
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Вобщем надоело мне ждать и я решил решить проблему. И решил.

Итак, есть 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)wink следующее:
!!! исходник нужно сохранять в кодировке 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)

Неактивен

 

#16 12-10-2005 11:05:36

Yurik
земля
Зарегистрирован: 22-04-2005
Сообщений: 115

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Nicck написал:

Если знаете что такое diff и patch то вот файлы:

а что такое diff и patch?

Неактивен

 

#17 12-10-2005 17:34:06

Denny
веди
Зарегистрирован: 03-08-2005
Сообщений: 26

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Nicck написал:

Есои сильно надо, говорите, может и допишу.

НАДО!!! Я думаю все будут премного благодарны.
И нужно бы ещё как-то связаться с Dean'ом или другими разработчиками и окончательно решить эту проблему в следующих релизах...

Неактивен

 

#18 12-10-2005 18:27:36

Nicck
ферт
Откуда: Ижевск
Зарегистрирован: 11-05-2005
Сообщений: 536
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

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

Если у вас нет текстового редактора wink то вот вам:
nck_search_mod.zip
уже готовые поправленные файлы, вам остаётся только заменить свои старые на них.

taghandlers.php там кстати, не тот, что был в поставке 4.0.1 когда я её качал,чуть посвежее, что-то там пофиксили.

Denny написал:

И нужно бы ещё как-то связаться с Dean'ом или другими разработчиками и окончательно решить эту проблему в следующих релизах...

Моё решение не универсально, т.е. правка publish.php конечно приводит к тому, что поиск в базе начинает работать, но вот новая функция search_result_excerpt() реализует подсветку только для кирилицы.

Вчерашний вариант кстати должен подойти всем, но у него есть недостаток (результаты поиска выводятся в нижнем регистре).
upd: это я погорячился, не подойдёт он тоже.

Отредактированно Nicck (13-10-2005 18:02:00)

Неактивен

 

#19 13-10-2005 11:07:49

glebotr
ять
Зарегистрирован: 25-06-2005
Сообщений: 1974
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Супер, в копилку.


Пх’нглуи мглв’нафх Ленин Красная площадь вгах’нагл фхтагн
(В своем доме на Красной площади мертвый Ленин спит, ожидая своего часа (ктулх.))

Неактивен

 

#20 13-10-2005 11:40:38

Evgeny
ять
Зарегистрирован: 15-03-2005
Сообщений: 1869

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

То что решение есть, это отлично!
Не надо забывать, что это - хак, со всеми связанными с этим проблемами по поддержке хака от версии к версии.
Может быть можно оформить его таким образом, чтобы менялась одна-две строчки в "родном" коде?

Неактивен

 

#21 13-10-2005 18:04:56

Nicck
ферт
Откуда: Ижевск
Зарегистрирован: 11-05-2005
Сообщений: 536
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Меняется *одна строчка* в publish.php
и *одна функция* в taghandlers.php
Не вижу никаких проблем и нужды ещё что-то придумывать. Всё и так максимально просто.

Неактивен

 

#22 14-10-2005 17:51:02

Evgeny
ять
Зарегистрирован: 15-03-2005
Сообщений: 1869

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

в принципе- да. тут дело уже личных предпочтений.

Неактивен

 

#23 13-03-2006 17:03:52

TAndrew
аз
Зарегистрирован: 27-09-2005
Сообщений: 4

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Есть ещё одна проблема: буквы «е» и «ё» считаются разными. Если в тексте в слове Ё, в ищется слово с буквой Е - то не найдёт. Как обойти подобное?

Неактивен

 

#24 13-03-2006 18:59:14

Nicck
ферт
Откуда: Ижевск
Зарегистрирован: 11-05-2005
Сообщений: 536
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

Дорабатываем решение:

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

Неактивен

 

#25 13-03-2006 19:06:50

Nicck
ферт
Откуда: Ижевск
Зарегистрирован: 11-05-2005
Сообщений: 536
Вебсайт

Re: Как "научить" поиск Textpattern игнорировать регистр букв в кирилице?

utf-8 !!!

Неактивен

 

Board footer

RSS   Rambler's Top100
Powered by PunBB
Textpattern.ru