Как преобразовать персидские цифры в UTF-8 в европейские цифры в ASCII?

В персидских цифрах ۰۱۲۳۴۵۶۷۸۹ эквивалентно 0123456789 в европейских цифрах.

Как преобразовать персидское число (в UTF-8 ) в ASCII?

Например, я хочу ۲۱ стать 21 .

  • потеря поддержки unicode urxvt при входе в систему как пользователь, корневая оболочка имеет их
  • Отсутствующие символы в моем URXVT
  • Найти лучший шрифт для рендеринга codepoint
  • Обновлен мой архивный linux-сервер, и теперь я получаю tmux: требуется локаль UTF-8 (LC_CTYPE), но имеет ANSI_X3.4-1968
  • Curl JSON кодируется в UTF-8
  • Экран GNU не отображает символы юникода правильно
  • поддержка кодировки utf-8 с lpr
  • Команда вроде `column -t`, но агностик типа кодирования?
  • 5 Solutions collect form web for “Как преобразовать персидские цифры в UTF-8 в европейские цифры в ASCII?”

    Мы можем воспользоваться тем, что кодовая точка UNICODE персидских цифр последовательна и упорядочена от 0 до 9 :

     $ printf '%b' '\U06F'{0..9} ۰۱۲۳۴۵۶۷۸۹ 

    Это означает, что последняя шестнадцатеричная цифра означает десятичное значение:

     $ echo $(( $(printf '%d' "'۲") & 0xF )) 2 

    Это делает этот простой цикл инструментом преобразования:

     #!/bin/bash ( ### Use a locale that use UTF-8 to make the script more reliable. ### Maybe something like LC_ALL=fa_IR.UTF-8 for you?. LC_ALL=en_US.UTF-8 a="$1" while (( ${#a} > 0 )); do # extract the last hex digit from the UNICODE code point # of the first character in the string "$a": printf '%d' $(( $(printf '%d' "'$a") & 15 )) a=${a#?} ## Remove one character from $a done ) echo 

    Используя его как:

     $ sefr.sh ۰۱۲۳۴۵۶۷۸۹ 0123456789 $ sefr.sh ۲۰۱ 201 $ sefr.sh ۲۱ 21 

    Обратите внимание, что этот код также может преобразовывать арабские и латинские цифры (даже если они смешанные):

     $ sefr.sh ۴4٤۵5٥۶6٦۷7٧۸8٨۹9٩ 444555666777888999 $ sefr.sh ٤٧0٠٦7١٣3٥۶٦۷ 4700671335667 

    Поскольку это фиксированный набор чисел, вы можете сделать это вручную:

     $ echo ۲۱ | LC_ALL=en_US.UTF-8 sed -e 'y/۰۱۲۳۴۵۶۷۸۹/0123456789/' 21 

    (или используя tr , но не GNU tr еще)

    Для того, чтобы sed распознал ваши персонажи, требуется установка вашего языка в en_US.utf8 (или лучше для локали, к которой относится набор символов).

    С perl :

     $ echo "۲۱" | perl -CS -MUnicode::UCD=num -MUnicode::Normalize -lne 'print num(NFKD($_))' 21 

    Для Python существует библиотека unidecode которая обрабатывает такие преобразования в целом: https://pypi.python.org/pypi/Unidecode .

    В Python 2:

     >>> from unidecode import unidecode >>> unidecode(u"۰۱۲۳۴۵۶۷۸۹") '0123456789' 

    В Python 3:

     >>> from unidecode import unidecode >>> unidecode("۰۱۲۳۴۵۶۷۸۹") '0123456789' 

    Поток SO на https://stackoverflow.com/q/8087381/2261442 может быть связан.

    / edit: Как указывал Wander Nauta в комментариях, и, как упоминалось на странице Unidecode, есть также версия оболочки unidecode/usr/local/bin/ if installed over pip ):

     $ echo '۰۱۲۳۴۵۶۷۸۹' | unidecode 0123456789 

    Чистая версия bash:

     #!/bin/bash number="$1" number=${number//۱/1} number=${number//۲/2} number=${number//۳/3} number=${number//۴/4} number=${number//۵/5} number=${number//۶/6} number=${number//۷/7} number=${number//۸/8} number=${number//۹/9} number=${number//۰/0} echo "Result is $number" 

    Испытали в моей машине Gentoo, и она работает.

     ./convert ۱۳۲ Result is 132 

    Выполнен как цикл, заданный список символов (от 0 до 9) для преобразования:

     #!/bin/bash conv() ( LC_ALL=en_US.UTF-8 local n="$2" for ((i=0;i<${#1};i++)); do n=${n//"${1:i:1}"/"$i"} done printf '%s\n' "$n" ) conv "۰۱۲۳۴۵۶۷۸۹" "$1" 

    И используется как:

     $ convert ۱۳۲ 132 

    Другой способ (довольно избыточный) с использованием grep :

     #!/bin/bash nums=$(echo "$1" | grep -o .) result=() for i in $nums do case $i in ۱) result+=1 ;; ۲) result+=2 ;; ۳) result+=3 ;; ۴) result+=4 ;; ۵) result+=5 ;; ۶) result+=6 ;; ۷) result+=7 ;; ۸) result+=8 ;; ۹) result+=9 ;; ۰) result+=0 ;; esac done echo "Result is $result" 

    Поскольку iconv не может казаться, что это будет выглядеть, следующим портом вызова будет использование утилиты tr :

     $ echo "۲۱" | tr '۰۱۲۳۴۵۶۷۸۹' '0123456789' 21 

    tr переводит один набор символов в другой, поэтому мы просто скажем, чтобы он перевел набор цифр фарси на набор латинских цифр.

    EDIT : Как указывает пользователь @cuonglm. Для этого требуется не-GNU tr , например tr на Mac, и для этого также требуется, чтобы $LC_CTYPE был установлен в en_US.UTF-8 .

    Interesting Posts

    Как заблокировать субдомен с помощью dnsmasq?

    1: 1. Ядро с ядерным статусом 3.16 или более поздней версии с использованием TC

    Работает ли ионика с планировщиком сроков?

    Использование find и sed для копирования 20-й строки многих файлов в один файл

    Является ли запуск программ полезным другим пользователям?

    Как удалить двойные кавычки и точки из файла

    Как вы можете запланировать загрузку компьютера в определенное время?

    Может только получить доступ к одной сети извне

    как создать более трех настраиваемых команд geany с ярлыками

    Добавление настраиваемого DNS-сервера для клиентского подключения pppd?

    Вручную подключиться к точке доступа Wi-Fi (AP), несмотря на предварительно сконфигурированные точки доступа в wpa_supplicant

    Как Ubuntu 14.04 достигает постоянных этажных интерфейсов?

    Создание закрытого ключа для существующего сертификата SSL

    Восстановление Windows XP с grub

    размер каталога в conky

    Linux и Unix - лучшая ОС в мире.