В персидских цифрах ۰۱۲۳۴۵۶۷۸۹
эквивалентно 0123456789
европейским цифрам.
Как я могу конвертировать персидское число (в UTF-8
) в ASCII?
Например, я хочу ۲۱
стать 21
.
bash
unicode
conversion
بارپابابا
источник
источник
echo "۰۱۲۳۴۵۶۷۸۹" | iconv -f UTF-8 -t ascii//TRANSLIT
, не справляется ...iconv
просто здесь для отображения символов в разных кодировках, но это символы (восточно-арабские цифры), которые не имеют эквивалента в ASCII, вы можете просто преобразовать их во что-то достаточно похожее, но это только односторонний характер.iconv
способен и не способен делать. Я надеялся, что//TRANSLIT
это поможет, но это не помогло.Ответы:
Мы можем воспользоваться тем фактом, что кодовая точка UNICODE персидских цифр является последовательной и имеет порядок от 0 до 9 :
Это означает, что последняя шестнадцатеричная цифра является десятичным значением:
Это делает этот простой цикл инструментом преобразования:
Используя это как:
Обратите внимание, что этот код может также преобразовывать арабские и латинские цифры (даже если они смешаны):
источник
'۰
. Это могло быть написано также как'"۰'
. Причина в том, что printf даст код UNICODE, если аргумент начинается с одинарной'
или двойной кавычки"
. Найдите немного перед этой ссылкой текст «Если главный символ - одинарная или двойная кавычка»Поскольку это фиксированный набор чисел, вы можете сделать это вручную:
(или используя
tr
, но еще не GNU )Установка вашей локали
en_US.utf8
(или, что лучше, локали, которой принадлежит набор символов) необходима дляsed
распознавания набора символов.С
perl
:источник
LC_ALL
необходима для того, чтобы каждый отдельный символ Юникода также рассматривался как таковойsed
, верно?tr
для этой конкретной цели?tr
того, как он не работает везде. Также имейте в виду, что некоторые инструменты оптимизированы для работы с байтами, в то время как другие предназначены для работы с символами, с Unicode (особенно UTF-8) это имеет огромное значение.LC_ALL
.LC_ALL
также не установлен в моей среде (ноLANG
установлен вen_GB.UTF-8
). С помощью приведенного выше кода я получаю ошибку «sed: 1:« y / ۰۱۲۳۴۵۶۷۸۹ / ... »: строки преобразования не имеют одинаковую длину».Для Python есть
unidecode
библиотека, которая обрабатывает такие преобразования в целом: https://pypi.python.org/pypi/Unidecode .В Python 2:
В Python 3:
Поток SO на /programming//q/8087381/2261442 может быть связан.
/ edit: Как отметил Вандер Наута в комментариях и как уже упоминалось на странице Unidecode, есть также версия оболочки
unidecode
(в/usr/local/bin/
случае установки поверхpip
):источник
unidecode
которая делает то же самое, что и ваш фрагмент Python 3. Простоecho '۰۱۲۳۴۵۶۷۸۹' | unidecode
должно работать.pip
его там.unidecode/util.py
- странно, что Debian не включает его. (Правка: Ах, загадка раскрыта. Пакет Debian устарел и старше, чем утилита.)Чистая версия Bash:
Протестировал на моей машине Gentoo и все работает.
Выполнено в виде цикла, учитывая список символов (от 0 до 9) для преобразования:
И используется как:
Другой (довольно излишний) способ использования
grep
:источник
grep
. На самом деле, я не понимаю ни этой строки, ни того, почему вы не задаетеresult=0
. Вы слишком осторожны, если в нем$1
есть что-то кроме цифр фарси?number=${number//۱/1}
и т. Д., И избегали быecho
иgrep
.Так
iconv
как кажется, что это невозможно, следующим портом захода будет использованиеtr
утилиты:tr
переводит один набор символов в другой, поэтому мы просто просим его перевести набор цифр фарси в набор латинских цифр.РЕДАКТИРОВАТЬ : Как пользователь @cuonglm указывает. Для этого требуется не-GNU
tr
, например,tr
на Mac, а также для$LC_CTYPE
него установлено значениеen_US.UTF-8
.источник
en_US.utf8
.