setlocale - "опять двойка"

Ashotovich

Новичок
setlocale - "опять двойка"

Всем доброго времени суток. У меня на хостинге установлены следующие русские локали:

ru_RU
ru_RU.iso88595
ru_RU.koi8r
ru_RU.utf8
russian
ru_UA
ru_UA.koi8u
ru_UA.utf8

Мне нужно, чтобы PHP нормально воспринимал русские символы для обработки массива $_POST в гегулярном выражении на предмет наличия в нем запрещенных символов (для preg_match используется \w, то есть - все буквы).
Ну так вот, если я вообще не ставлю в скриптах setlocale(), то PHP не воспринимает букву "ч" за нормальную русскую букву, если же я ставлю setlocale(LC_ALL, "russian") или setlocale(LC_ALL, "ru_RU"), то перестают восприниматься буквы "р" и "э".
Как мне быть? Сразу скажу, что тиранить провайдерских админов на предмет установки локали ru_CP1251 - сизифов труд (хотя, если это - единственный разумный выход, то я там таки устрою бучу).
Может, как-то по-другому регулярное выражение построить (сейчас оно выглядить так: preg_match("/[^\w@+.,&№ \/\":-]/", join($_POST)))?

Заранее спасибо за помощь.
 

Ashotovich

Новичок
Блин. Установили они там локаль ru_RU.cp1251, проставил я ее при помощи setlocale(LC_ALL, "ru_RU.cp1251"). И что же? Теперь мое регулярное выражение отбрасывает ВСЕ буквы русского алфавита.
Подскажите, \w - это все буквы данной локали, или же - только латинские? Что-то меня начали брать сомнения...

P.S. Содержит ли класс [а-яА-Я] букву Ё?
 

Profic

just Profic (PHP5 BetaTeam)
1) locale -l
2) echo setlocale (LC_ALL, 'точное имя локали');
да еще в догонку
1) имя у локали регистрозависимое
2) под виндой имеет другие имена, что-то типа Russian_Russia.1251
 

Ashotovich

Новичок
На сервере стоит Линукс. Когда я в консоли набираю locale -a мне выдается список всех локалей; cp1251 так и называется - ru_RU.cp1251 (cp - маленькими буквами, что подозрительно...).

Да, я плюнул на все и просто добавил русские буквы в класс:
preg_match("/[^\wа-яА-ЯёЁ@+.,&№ \/\":-]/", join($_POST))

Так, вроде, работает. Но вопрос о \w все еще висит в воздухе - так и не понял, почему оно не включает в себя русских букв...
 

Profic

just Profic (PHP5 BetaTeam)
гыгыгы
у тебя такое регулярное выражение, что при правильно установленной локали будет совпадать с любой строкой, которая не начинается (один симол)на добрую кучу символов, в том числе и русские/английские буквы и цифры
Регулярку свою проверь, а?
 

Ashotovich

Новичок
preg_match('/[^\wа-яА-ЯёЁ@+.,&№ \/":-]/', join($_POST)) - вот разве что так можно... Что в ней не так?
 

Ashotovich

Новичок
Да нет. Слешить не надо - знак ^ означает отрицание класса. Правда, в мануале сказано, что "negate the class, but only if the first character", но выражение работает - можете сами проверить. Оно должно отслеживать наличие в массиве $_POST символов, не принадлежащих к классу [все буквы русского и латинского алфавита, собака, плюс, точка, запятая, "энд", "номер", пробел, прямой слеш, двойные кавычки, двоеточие, тире].
Я не знаю, как оно так вдруг заработало. Вроде, и соешить в классе ничего нельзя - обратный слеш может в этот же класс попасть - но не попал же! Можете проверить. Вроде бы, символ ^ означает отрицание класса за исключением первого символа (или я как-то не так понял)... Но не исключает он его! Весь класс отрицает.

Помогите разобраться, пожалуйста. (мде. Тема в оффтоп опять ушла. Прошу простить.)
 

Profic

just Profic (PHP5 BetaTeam)
учись студент:
1) preg_match ('~^[\w@+.,&№ /":-]+$~', $str);
В нормальных системах, по умолчанию не разрешено все и что-то запрещено, а запрещено все и что-то разрешено.
2) как прикажете понимать вот это: join ($_POST), интересный код, честное слово, учитывая вот это:
string join (string glue, array pieces)
 

Ashotovich

Новичок
2 Profic:
А нельзя ли поподробнее - что было и что стало? Пожалуйста.
Например, я не нашел в мануале описания тильды (~) - это просто deliminator? И зачем использутеся знак плюса?

Насчет второго замечания - цитирую мануал по [m]implode()[/m] (то бишь по алиасу join):

Notе:
As of PHP 4.3.0, the glue parameter of [m]implode()[/m] is optional and defaults to the empty string(''). This is not the preferred usage of [m]implode()[/m]. We recommend to always use two parameters for compatibility with older versions.

Так что такой синтаксис допустим, если не заботиться о совместимости с версиями PHP до 4.3.0.
 

Profic

just Profic (PHP5 BetaTeam)
Немного достал уже...
>это просто deliminator?
да именно он, там может быть какой угодно небуквенный символ
>И зачем использутеся знак плюса?
затем, что "В нормальных системах, по умолчанию не разрешено все и что-то запрещено, а запрещено все и что-то разрешено"
>что было и что стало?
было, то что было: любой символ не из класса [] вызывал возврат 1 из preg_match
стало, то что есть: ф-ция preg_match возращает 1 только в том cлучае когда вся строка от начала и до конца содержит символы из класса []
А насчет note-а: а ты уверен, что хочешь отсечь всех пользователей, которые используют пхп < 4.3.0. Если пишешь конкретно под конфигурацию, то пофигу, если же нет то можешь напороться :)
 

Ashotovich

Новичок
Понял. Бум думать. Спасибо!

Да, пишется под конкретную кофигурацию. Я бы сказал - конкретную организацию... ;)
 
Сверху