Если вдруг кто заметил, у меня на бложеке появился фильтр русского мата! В действии можно посмотреть например в посте про лук, предсказуемо содержащем неприличное слово. Как это сделано - напишу чуть позже. Пока кодил - столкнулся с проблемой: на моем новом сервере (куда я переехал с Агавы в начале года) не было русских локалей, вообще. Соответственно, регулярки не ловили слово из трех букв, если первая буква - заглавная, например. Пришлось устанавливать, а заодно писать очередной пост в "красноглазие".
Установил, работает. Записываю на память, пошагово.
1. Проверяем, что есть русского
> locale -a | grep ru
Должен показать локали, содержащие "ru" в названии. В моем случае не показал ничего.
2. Проверяем, что вообще есть
> locale -a
Отображает установленные в системе локали - все, какие есть. У меня оказалось:
C
POSIX
Не густо, ага :(
3. Смотрим локали доступные, но не установленные:
> cd /usr/share/i18n/locales/
> ls -la | grep ru
То есть переходим в папку, откуда ставятся локали, и ищем там файлы с подстрокой "ru". Я нашел такие:
-rw-r--r-- 1 root root 5445 Jun 6 2010 ru_RU
-rw-r--r-- 1 root root 5157 Jun 6 2010 ru_UA
4. Смотрим чармэпы:
> cd /usr/share/i18n/charmaps/> ls -la | grep 1251
Меня интересует кодировка windows-1251, поэтому я и искал charmap-файл с этой кодировкой. Нашел вот что:
-rw-r--r-- 1 root root 2873 Jun 6 2010 CP1251.gz
5. Делаем локальдеф
> localedef -i ru_RU -f CP1251 ru_RU.CP1251
Собственно, вся магия сосредоточена в этой команде - при помощи нее мы на основе файла локали и файла charmap устанавливаем в систему новую локаль, которой потом можем пользоваться.
6. Проверяем, что локаль добавилась
> locale -a
Ну, как во втором пункте, но теперь с другим результатом:
C
POSIX
ru_RU.cp1251
Ура, есть контакт!
6. Перезапускаем апач
> /etc/init.d/apache2 restart
У меня до перезапуска веб-сервера ничего не запахало. Капитан Очевидность подсказывает, что команда выше работает для Apache 2 :)
7. Пишем тест
Если все заработало, регулярки с модификатором i (case insensitive) должны находить заглавные буквы. Проверяем, так ли это:
<?
putenv ("LC_ALL=ru_RU");
$locale = setlocale(LC_ALL, 'ru_RU.cp1251');
echo "Locale is '".$local."'";
preg_match_all('~[а-я]~i', 'Раз дВа', $matches);
echo "<pre>".htmlspecialchars(print_r($matches,1))."</pre>";
?>
У меня заработало, завидуйте :) "Заработало" - значит, что я могу например при помощи strtoupper() получить из строки готовые оффшорные компании строку "ГОТОВЫЕ ОФФШОРНЫЕ КОМПАНИИ", или искать по этой строке регулярками, регулируя чувствительность к регистру.