Как удалить акценты и превратить буквы в "простые" символы ASCII?

Каков наиболее эффективный способ удаления акцентов из строки, например. ÈâuÑ становится Eaun?

Есть ли простой, встроенный способ, который мне не хватает или регулярное выражение?

Ответ 1

Если вы установили iconv, попробуйте это (пример предполагает, что ваша строка ввода находится в UTF-8):

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

(iconv - это библиотека для преобразования между всеми типами кодировок, она эффективна и включена во многие дистрибутивы PHP по умолчанию. В первую очередь, это определенно проще и эффективнее, чем попытка опрокинуть собственное решение (знаете ли вы что там "латинская буква N с завитом"? Мне и не.))

Ответ 2

Я нашел решение, которое работало во всех моих тестовых случаях (скопировано из http://php.net/manual/en/transliterator.transliterate.php):

var_dump(transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove',
    "A æ Übérmensch på høyeste nivå! И я люблю PHP! есть. fi ¦"));
// string(50) "A ae Ubermensch pa hoyeste niva! I a lublu PHP! est. fi "

см. http://www.php.net/normalizer

EDIT: Это решение не зависит от набора локалей, использующего setlocale(). Еще одно преимущество над iconv() заключается в том, что даже не латинские символы не игнорируются.

EDIT2: Я обнаружил, что есть некоторые символы, которые не покрываются транслитерацией, которую я опубликовал первоначально. Any-Latin переводит кириллический символ ь символу, который не вписывается в латинский набор символов: ʹ (http://en.wikipedia.org/wiki/Prime_%28symbol%29). Я добавил [\u0100-\u7fff] remove, чтобы удалить все эти нелатинские символы. Я также добавил тест к тексту;)

Я предлагаю, что они означают латинский алфавит, а не один из латинских символов на Latin здесь. Но в любом случае - на мой взгляд, они должны транслитерировать его на нечто ASCII, а затем в Latin-ASCII...

EDIT3: Извините за другое изменение здесь. Я должен был взять символы до u0080 вместо u0100, чтобы получить только символы ASCII в качестве вывода. Приведенный выше тест обновлен.

Ответ 3

Отправляя это по запросу @palantir...

Я нахожу iconv совершенно ненадежным, и мне не нравятся решения preg_replace и большие массивы... так что мой любимый способ (и единственный надежный метод, который я нашел) - это...

function toASCII( $str )
{
    return strtr(utf8_decode($str), 
        utf8_decode(
        'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'),
        'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy');
}

Ответ 4

Вы можете использовать iconv для транслитерации символов в обычный US-ASCII, а затем использовать регулярное выражение для удаления неалфавитных символов:

preg_replace('/[^a-z]/i', '', iconv("UTF-8", "US-ASCII//TRANSLIT", $text))

Другим способом будет использование Normalizer для нормализации к Нормализация формы KD (NFKD), а затем удалить знаки метки:

preg_replace('/\p{Mn}/u', '', Normalizer::normalize($text, Normalizer::FORM_KD))

Ответ 5

Примечание. Я переписываю это из другого подобного вопроса в надежде, что он будет полезен другим.

В итоге я написал PHP-библиотеку на основе URLify.js из проекта Django, так как я обнаружил, что iconv() слишком неполный. Вы можете найти его здесь:

https://github.com/jbroadway/urlify

Обрабатывает латинские буквы, а также греческий, турецкий, русский, украинский, чешский, польский и латышский.