Проблема в стемере для PHP
В модуле stem для ПХП обнаружилась неожиданная проблема. Этот модуль — стеммер, позволяющий обрезать окончания слов для того, чтобы искать потом по тексту без учёта падежей и склонений.
Для русского языка в нём целых две функции — для кодировки
Я обратил внимание, что из командной строки код с этим модулем работает нормально, а в рабочем проекте кодировка портится — как будто стеммер
У меня возникла мысль, что дело в выставляемой локали, мы провели эксперимент — так и есть, дело в этом. Такой код работать правильно не будет:
setlocale(LC_TIME, 'ru_RU.cp1251');
echo stem_russian_unicode(iconv('windows-1251', 'utf-8', 'Приветы'));Кодировка получится битой. Перед вызовом функций стеммера нужно переставлять кодировку (setlocale)
// файл stem.c
php_strtolower(z->p, arglen); // ← вот искомый вызов
stem(z);
z->p[z->l]= '\0';
// … ищем эту функцию в исходниках PHP…
// string.c из PHP
PHPAPI char* php_strtolower(char * s, size_t len) {
unsigned char *c, *e;
c = (unsigned char *)s;
e = c+len;
while (c < e) {
*c = tolower(*c); // ← а это проблемное место
c++;
}
return s;
}Согласно манам, функция tolower ориентируется в своей работе на локаль, в этом и проблема.
Комментарии 7
Люди вообще ко многому плохому привыкли. К «кавычкам» от печатающих машинок, отсутствию падежей у Домодедово, к написанию McDonald's на российских забегаловках этой сети, к юзанью иностранных слов, там где есть свои и так далее :)
Когда я писал «КС1251» я не имел ввиду «кодировка с названием „CP1251“», я имел ввиду «кодовая страница 1251».