Каков наиболее эффективный способ удаления акцентов из строки, например, ÈâuÑ
становится Eaun
?
Есть ли простой, встроенный способ, которым я отсутствую или регулярное выражение?
Если вы установили iconv, попробуйте это (пример предполагает, что ваша строка ввода находится в UTF-8):
echo iconv('UTF-8', 'ASCII//TRANSLIT', $string);
(iconv – это библиотека для преобразования между всеми типами кодировок, она эффективна и включена во многие дистрибутивы PHP по умолчанию. В первую очередь, это определенно проще и надежнее, чем пытаться опрокинуть собственное решение (знаете ли вы, что есть «Латинская буква N с завитом»? Я тоже .))
Я нашел решение, которое работало во всех моих тестовых сценариях (скопировано из 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 в качестве вывода. Приведенный выше тест обновлен.
Отправляя это по запросу @palantir …
Я нахожу iconv совершенно ненадежным, и мне не нравятся решения preg_replace и большие массивы … так что мой любимый способ (и единственный надежный метод, который я нашел) – это …
function toASCII( $str ) { return strtr(utf8_decode($str), utf8_decode( 'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'), 'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy'); }
Вы можете использовать iconv
для транслитерации символов в обычный US-ASCII, а затем использовать регулярное выражение для удаления неалфавитных символов:
preg_replace('/[^az]/i', '', iconv("UTF-8", "US-ASCII//TRANSLIT", $text))
Другой способ – использовать нормализатор для нормализации к форме нормализации KD (NFKD), а затем удалить знаки метки:
preg_replace('/\p{Mn}/u', '', Normalizer::normalize($text, Normalizer::FORM_KD))
Примечание. Я переписываю это из другого подобного вопроса в надежде, что он будет полезен другим.
Я закончил писать PHP-библиотеку на основе URLify.js из проекта Django, так как я обнаружил, что iconv () слишком неполный. Вы можете найти это здесь:
https://github.com/jbroadway/urlify
Обрабатывает латинские символы, а также греческий, турецкий, русский, украинский, чешский, польский и латышский.