Мне нужно «сгладить» ряд строк Unicode для целей индексирования и поиска. Например, мне нужно преобразовать GötheФ€
в ASCII. Последние два символа не имеют близких представлений в ASCII, поэтому их можно полностью отбросить. Так что я ожидаю от
echo iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", "GötheФ€");
это Gothe
но вместо этого он выводит Gothe?EUR
.
Помимо букв, мне также хотелось бы, чтобы все разновидности цифр Юникода и знаков препинания, таких как периоды, запятые, тире, слэши и т. Д., Были заменены их ближайшими аналогами ASCII, что-то вроде ASCII//TRANSLIT//IGNORE
в функции iconv
уже, но не без производства какого-либо вывода мусора для символов Unicode, для которого он не может найти никаких замен ASCII. Я бы хотел, чтобы такие персонажи были полностью проигнорированы.
Как получить ожидаемый результат? Есть ли лучший способ, возможно, с помощью библиотеки intl
?
Вы столкнулись с серьезной проблемой. Лучше сказать, что пользователь вводит символы Unicode для транслитерации самих ASCII. Выполнение этого для них будет только расстраивать их, когда они не согласны с вашей транслитерацией.
Все, что вы делаете, скорее всего, будет раздражать и оскорбительно для людей, которые придают большое значение диакритике: http://en.wikipedia.org/wiki/Diacritic
Независимо от того, какую стратегию транслитерации вы используете, вы не будете нравиться всем, так как разные люди предписывают разные значения различным персонажам. Транслитерация, которая радует одного человека, будет злить другого. Вы не сделаете всех счастливыми, если только вы не позволяете всем использовать любой символ, который они хотят в Юникоде.
Но жизнь суетливая и оскорбительная, поэтому мы идем:
Этот код PHP:
function toASCII( $str ) { return strtr(utf8_decode($str), utf8_decode( 'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'), 'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy'); }
То, что делает эта функция PHP, заменяет каждый символ Юникода в первом параметре utf8_decode и заменяет его соответствующим символом во втором параметре utf8_decode.
Например, Unicode À
транслитерируется в ASCII A
, а å
преобразуется в a
. Вы должны указать это для каждого символа Unicode, который, по вашему мнению, транслитерирует символ ASCII. Для остальных удалите их или запустите их через другой алгоритм транслитерации.
Есть еще 95.221 других персонажей, которые вам понадобятся, чтобы посмотреть, что может транслитерировать в ASCII. Это становится экзистенциальной игрой «Когда A
больше не A
?». Как насчет персонажей клингонов и дорожных карт, которые выглядят как A? Характер вида рыбы выглядит как a
. Кто скажет, что это?
Это большая работа, но если вы очищаете ввод базы данных, вам нужно создать белый список символов и заблокировать других варваров, сохранив их в рю, это единственный надежный способ.
Этот комментарий php.net о функциональности Intl Normalizer может быть полезен :