рассмотрите этот простой код:
echo iconv('UTF-8', 'ASCII//TRANSLIT', 'è');
он печатает
`e
а не просто
e
Знаете ли вы, что я делаю неправильно?
после добавления setlocale ничего не изменилось
setlocale(LC_COLLATE, 'en_US.utf8'); echo iconv('UTF-8', 'ASCII//TRANSLIT', 'è');
У меня есть эта стандартная функция, чтобы возвращать действительные строки url без недопустимых символов url. Кажется, что магия находится в строке после // удаления комментариев нежелательных символов .
Это взято из документационной документации Symfony: http://www.symfony-project.org/jobeet/1_4/Doctrine/en/08, которая, в свою очередь, взята из http://php.vrana.cz/vytvoreni-pratelskeho- url.php, но я не говорю по-чешски 😉
function slugify($text) { // replace non letter or digits by - $text = preg_replace('#[^\\pL\d]+#u', '-', $text); // trim $text = trim($text, '-'); // transliterate if (function_exists('iconv')) { $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); } // lowercase $text = strtolower($text); // remove unwanted characters $text = preg_replace('#[^-\w]+#', '', $text); if (empty($text)) { return 'n-a'; } return $text; } echo slugify('é'); // --> "e"
cf @tchrist, с расширением INTL php
http://fr2.php.net/manual/en/book.intl.php
preg_replace('/\pM*/u','',normalizer_normalize( $mystring, Normalizer::FORM_D));
eéèêëîïoöôuùûüaâäÅ Ἥ ŐǟǠ ǺƶƈƉųŪŧȬƀ␢ĦŁȽŦ ƀǖ становится
eeeeeiiiooouuuuaaaA Η OaA AƶƈƉuUŧOƀ␢ĦŁȽŦ ƀu
Как подчеркивает tchrist, не все символы Юникода считаются разложимыми:
извлечение из диаграмм Unicode:
U0080.pdf
00CF Ï ЛАТИНСКОЕ КАПИТАЛ ПИСЬМО I С ДИАЕРЕЗОМ
≡ 0049 I 0308 ¨
NB этот символ «≡» указывает на доступное разложение
00D0 ì ПИСЬМО ЛАТИНСКОГО КАПИТАЛА ETH
→ 00F0 ð latin small letter eth
→ 0110 Đ латинская прописная буква d с инсультом
→ 0189 Ɖ латинская прописная буква african d
нет разложения, IMHO странно (мы могли бы рассматривать букву A ASCII как приемлемый эквивалент).
U0100.pdf
0110 Đ ЛАТИНСКОЕ КАПИТАЛНОЕ ПИСЬМО D С ТРОКОМ
→ 00D0 ì латинская прописная буква eth
→ 0111 đ латинская маленькая буква d с инсультом
→ 0189 Ɖ латинская прописная буква african d
даже незнакомец: этот идентифицируется как LATIN CAPITAL LETTER D (с инсультом), но не разлагаемый как таковой! Возможно, более крутое решение должно состоять в том, чтобы получить описание юникода каждого символа и сравнить его с описанием каждого символа ascii (и соответственно заменить). Кто угодно? ; -]
При выполнении транслитерации вы должны убедиться, что ваш LC_COLLATE установлен правильно, в противном случае будет использоваться POSIX по умолчанию.
Посмотрите http://uk3.php.net/manual/en/function.setlocale.php
Я испытываю соблазн сказать «ничего», хотя это немного вне моего опыта. PHP iconv () является печально известным и вдохновляет многих обходных решений, в том числе
Прочтите комментарии для документации iconv () для большего количества вдохновения. (Или состязание. Слишком близко к вызову.)
Кажется, что стандартный способ справиться с этим – с помощью функции «удаления акцентов», которую вы можете найти в библиотеке, например, в расцветке или в CMS, например WordPress . Iconv, похоже, не в состоянии перевести акценты (и это правильно), поскольку это не очень хорошая идея для чего-либо, кроме URL-пулов.
Это происходит со мной с чистым iconv без php. Трюк должен был установить значение среды LANG в en_US.UTF-8 (это было hu_HU.UTF-8 раньше, в моем случае). После того, как он работал, как ожидалось.
Кажется, что это зависит от версии php …
php -version
PHP 7.0.0RC8 ( cli ) (построено: 25 ноября 2015 г. 12:36:50) (NTS) Copyright (c) 1997-2015 PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies с Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, Zend Technologies
php -r "var_dump(iconv('UTF-8', 'ASCII//TRANSLIT', 'è'));" string(2) "`e"
php -version
PHP 7.0.8-1 ~ dotdeb + 8.1 (cli) (NTS) Copyright (c) 1997-2016 PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies с Zend OPcache v7.0.8-1 ~ dotdeb + 8.1, Copyright (c) 1999-2016, Zend Technologies
php -r "var_dump(iconv('UTF-8', 'ASCII//TRANSLIT', 'è'));" string(1) "e"