UTF8 и preg_replace

leosun

Новичок
UTF8 и preg_replace

Никак не хочет работать $search в кодировке UTF-8

PHP:
$search = preg_replace("#[^a-zа-я ]#i",'',$search);
echo $search;
die();
ни так

PHP:
$search = iconv('UTF-8','cp1251',$search);
$search = preg_replace("#[^a-zа-я ]#i",'',$search);
$search = iconv('cp1251','UTF-8',$search);
ни так

PHP:
setlocale(LC_CTYPE, 'ru_RU.utf-8');
$search = preg_replace("#[^a-zа-я ]#i",'',$search);
ума не приложу что еще сделать =(
 

sage

Новичок
вдогонку вопрос по этой же теме)

PHP:
setlocale(LC_ALL, 'ru_RU.UTF-8');
...
var_dump(preg_replace('!\W!u', '', '!проверка!')); // string(0) ""
вместо ожидаемой "проверка". почему не работают \W и \w?

спасибо
 

alexcrown

Новичок
Потому что \W (символ не слова) как и \w зависит от локали и возможно не корректно работает с unicode.
В Unicode \w -- это символы с General_Category равной (Letter|Mark|Number|Connector_Punctuation).

Вообще с unicode лучше работают функции mb_ereg_% (доступны, если включено расширение mbstring). Там это вглядит вот так:
PHP:
mb_regex_encoding('UTF-8');
$search = mb_ereg_replace('\W', '', '!проверка!');
var_dump($search); // string(16) "проверка"
 

sage

Новичок
Потому что \W (символ не слова) как и \w зависит от локали и возможно не корректно работает с unicode.
вот мне это и интересно, почему некорректно работает... По Фридлу "При поддержке Юникода \w обычно соответствует любому алфавитно-цифровому символу..." Модификатор u стоит...
В Unicode \w -- это символы с General_Category равной (Letter|Mark|Number|Connector_Punctuation).
и что это означает?)
 

alexcrown

Новичок
Вот что нашел в документации PCRE (той что в исходниках php):
6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly
test characters of any code value, but the characters that PCRE recog-
nizes as digits, spaces, or word characters remain the same set as
before, all with values less than 256. This remains true even when PCRE
includes Unicode property support, because to do otherwise would slow
down PCRE in many common cases. If you really want to test for a wider
sense of, say, "digit", you must use Unicode property tests such as
\p{Nd}.
Т.е. эти последовательности в целях повышения производительности срабатывают только для символов с кодом меньше 255, а русские буквы в юникоде естественно гораздо дальше
 
Сверху