php iconv транслит для удаления акцентов: не работает как исключение? - PullRequest
8 голосов
/ 06 февраля 2011

рассмотрите этот простой код:

echo iconv('UTF-8', 'ASCII//TRANSLIT', 'è');

печатает

 `e

вместо

 e

Вы знаете, что я делаю неправильно?


ничего не изменилось после добавления setlocale

setlocale(LC_COLLATE, 'en_US.utf8');
echo iconv('UTF-8', 'ASCII//TRANSLIT', 'è');

Ответы [ 7 ]

9 голосов
/ 06 февраля 2011

У меня есть эта стандартная функция, чтобы возвращать действительные строки 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"
7 голосов
/ 08 августа 2012

cf @tchrist, с расширением INTL php

http://fr2.php.net/manual/en/book.intl.php

preg_replace('/\pM*/u','',normalizer_normalize( $mystring, Normalizer::FORM_D));

eeèêëiîïoöôuùûüaâäÅ Ἥ ŐǟǠ ǺƶƈƉųŪŧȬƀ␢ĦŁȽŦ ƀǖ становится

eeeeeiiiooouuuuaaaA Η OaA AƶƈƉuUŧOƀ␢ĦŁȽŦ ƀu


Как подчеркивает Трист, не все символы Юникода считаются разложимыми:

извлечение из диаграмм Юникода:

U0080.pdf

00CF Ï ПИСЬМО ЛАТИНСКОГО КАПИТАЛА I С ДИАРЕЗОМ

≡ 0049 I 0308 ¨

NB этот символ «≡» обозначает доступное разложение

00D0 Ð ПИСЬМО ЛАТИНСКОГО КАПИТАЛА ETH

→ 00F0 ð латинская строчная буква eth

→ 0110 Đ латинская заглавная буква d со штрихом

→ 0189 Ɖ латинская заглавная букваd

нет декомпозиции, ИМХО странно (мы могли бы считать букву D ASCII приемлемым эквивалентом).

U0100.pdf

0110 Đ ЛАТИНСКИЙКАПИТАЛЬНОЕ ПИСЬМО D WITH STROKE

→ 00D0 ì латинская заглавная буква eth

→ 0111 small латинская строчная буква d со штрихом

→ 0189 Ɖ латинская заглавная буква африканский d

даже незнакомец: этот текст обозначен как LATIN CAPITAL LETTER D (с ударом), но не разлагается как таковой!Возможно, более удачное решение должно заключаться в том, чтобы получить описание в юникоде каждого символа и сравнить его с описанием каждого символа ascii (и заменить соответственно).Кто-нибудь?; -]

ср http://unicode.org/Public/UNIDATA/UnicodeData.txt

2 голосов
/ 01 июля 2013

Это случилось со мной с чистым iconv без php. Хитрость заключалась в том, чтобы установить значение среды LANG в en_US.UTF-8 (в моем случае это был hu_HU.UTF-8). После того, как все заработало, как и ожидалось.

0 голосов
/ 02 августа 2016

Кажется, что это зависит от версии php ...


TestCase # 1

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, Авторское право (c) 1999-2015, Zend Technologies

php -r "var_dump(iconv('UTF-8', 'ASCII//TRANSLIT', 'è'));"

string(2) "`e"

TestCase # 2

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, Авторское право (c) 1999-2016Zend Technologies

php -r "var_dump(iconv('UTF-8', 'ASCII//TRANSLIT', 'è'));"

string(1) "e"
0 голосов
/ 28 октября 2011

Кажется, что стандартный способ справиться с этим - использовать функцию «удаления акцентов», которую вы можете найти в библиотеке, например, flourish или в CMS, например Wordpress .Iconv, похоже, не может перевести акценты (и это правильно), поскольку это не очень хорошая идея для чего-либо, кроме URL-слагов.

0 голосов
/ 06 февраля 2011

Я испытываю желание сказать «ничего», хотя это немного не в моей компетенции. PHP-iconv () печально известен и является источником вдохновения для многих обходных путей, включая

  • сброс к значку системы утилита (Unix & Linux)
  • создание справочного стола
  • замена всех акцентированных символов с эквивалентом ASCII как вид этап предварительной обработки
  • установка LC_COLLATE (который не кажется, работает для всех)
  • использовать htmlentities () вместо iconv ()

Прочитайте комментарии к iconv () документации для большего вдохновения (Или сочувствие. Слишком близко, чтобы позвонить.)

0 голосов
/ 06 февраля 2011

При выполнении транслитерации вы должны убедиться, что ваш LC_COLLATE установлен правильно, в противном случае будет использоваться POSIX по умолчанию.

Посмотрите на http://uk3.php.net/manual/en/function.setlocale.php

...