페르시아 숫자 에서 유럽 숫자 ۰۱۲۳۴۵۶۷۸۹
와 같습니다 0123456789
.
페르시아 숫자 (in UTF-8
)를 ASCII 로 변환하려면 어떻게 해야합니까?
예를 들어, 내가 원하는 ۲۱
되기 위해 21
.
답변
우리는 페르시아 숫자의 UNICODE 코드 포인트가 연속적이며 0에서 9까지의 순서 라는 사실을 이용할 수 있습니다 .
$ printf '%b' '\U06F'{0..9}
۰۱۲۳۴۵۶۷۸۹
즉, 마지막 16 진수는 10 진수 값입니다.
$ 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 아직)
에 로케일 설정 en_US.utf8
(또는 문자 세트가 속해있는 로케일 이상)에 필요한 sed
캐릭터 설정 인식.
로 perl
:
$ echo "۲۱" |
perl -CS -MUnicode::UCD=num -MUnicode::Normalize -lne 'print num(NFKD($_))'
21
답변
파이썬 들어있다 unidecode
: 일반적으로 이러한 변환을 처리하는 라이브러리 https://pypi.python.org/pypi/Unidecode은 .
파이썬 2에서 :
>>> from unidecode import unidecode
>>> unidecode(u"۰۱۲۳۴۵۶۷۸۹")
'0123456789'
파이썬 3에서 :
>>> from unidecode import unidecode
>>> unidecode("۰۱۲۳۴۵۶۷۸۹")
'0123456789'
/programming//q/8087381/2261442 의 SO 스레드 가 관련 될 수 있습니다.
/ edit : Wander Nauta가 주석에서 지적했듯이 Unidecode 페이지에서 언급했듯이 셸 버전도 있습니다 unidecode
( /usr/local/bin/
설치된 경우 아래 pip
).
$ echo '۰۱۲۳۴۵۶۷۸۹' | unidecode
0123456789
답변
순수한 배쉬 버전 :
#!/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"
내 젠투 머신에서 테스트했는데 작동합니다.
./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
한 문자 집합을 다른 문자 집합으로 변환하므로 단순히 Farsi 숫자 집합을 라틴 숫자 집합으로 변환하도록 지시합니다.
편집 : @cuonglm 사용자가 지적한대로. 이를 위해서는 Mac과 tr
같은 비 GNU 가 tr
필요하고 $LC_CTYPE
로 설정되어 있어야합니다 en_US.UTF-8
.