En números persas, ۰۱۲۳۴۵۶۷۸۹
es equivalente a 0123456789
en dígitos europeos.
¿Cómo puedo convertir el número persa (in UTF-8
) a ASCII?
Por ejemplo, quiero ۲۱
ser 21
.
bash
unicode
conversion
بارپابابا
fuente
fuente
echo "۰۱۲۳۴۵۶۷۸۹" | iconv -f UTF-8 -t ascii//TRANSLIT
no lo maneja ...iconv
es solo aquí para mapear caracteres en diferentes codificaciones, pero estos son caracteres (números arábigos orientales) que no tienen equivalente en ASCII, solo puede convertirlos en algo lo suficientemente similar, pero solo es unidireccional.iconv
era capaz y no capaz de hacer. Esperaba que usarlo me//TRANSLIT
ayudara, pero no fue así.Respuestas:
Podemos aprovechar el hecho de que el punto de código UNICODE de los números persas es consecutivo y está ordenado de 0 a 9 :
Eso significa que el último dígito hexadecimal ES el valor decimal:
Eso hace que este bucle simple sea una herramienta de conversión:
Utilizándolo como:
Tenga en cuenta que este código también podría convertir números arábigos y latinos (incluso si se mezclan):
fuente
'۰
. Podría haber sido escrito también como'"۰'
. La razón es que printf le dará el punto de código UNICODE si el argumento comienza con una comilla simple'
o una comilla doble"
. Busque un poco antes de este enlace el texto "Si el personaje principal es una comilla simple o una comilla doble"Como es un conjunto fijo de números, puedes hacerlo a mano:
(o usando
tr
, pero aún no GNU tr )Es necesario establecer su configuración regional en
en_US.utf8
(o mejor configuración regional a la que pertenece el conjunto de caracteres) parased
reconocer su conjunto de caracteres.Con
perl
:fuente
LC_ALL
Es necesario configurarlo para que todos los caracteres unicode también sean considerados como tales porsed
, ¿verdad?tr
para este propósito exacto?tr
cómo no funciona en todas partes. También tenga en cuenta que algunas herramientas están optimizadas para tratar con bytes, mientras que otras son para tratar con caracteres, con Unicode (especialmente UTF-8) esto hace una gran diferencia.LC_ALL
.LC_ALL
tampoco está configurado en mi entorno (peroLANG
está configurado enen_GB.UTF-8
). Con el código anterior, aparece el error "sed: 1:" y / ۰۱۲۳۴۵۶۷۸۹ / ... ": las cadenas de transformación no tienen la misma longitud".Para Python existe la
unidecode
biblioteca que maneja tales conversiones en general: https://pypi.python.org/pypi/Unidecode .En Python 2:
En Python 3:
El hilo SO en /programming//q/8087381/2261442 podría estar relacionado.
/ edit: Como señaló Wander Nauta en los comentarios y como se menciona en la página de Unidecode, también hay una versión de shell
unidecode
(debajo de/usr/local/bin/
si está instaladapip
):fuente
unidecode
que hace lo mismo que su fragmento de Python 3. Soloecho '۰۱۲۳۴۵۶۷۸۹' | unidecode
debería funcionar.pip
, está allí.unidecode/util.py
- extraño que Debian no lo incluya. (Editar: Ah, misterio resuelto. El paquete Debian está desactualizado y es más antiguo que la utilidad.)Una versión pura bash:
Lo he probado en mi máquina Gentoo y funciona.
Hecho como un bucle, dada la lista de caracteres (de 0 a 9) para convertir:
Y usado como:
Otra forma (más bien exagerada) usando
grep
:fuente
grep
. De hecho, no entiendo esa línea, ni por qué no estableceresult=0
. ¿Estás siendo demasiado cauteloso en caso de que$1
contenga otras cosas que no sean dígitos farsi?number=${number//۱/1}
etc., y evitarían elecho
ygrep
.Como
iconv
parece que no puede asimilar esto, el siguiente puerto de escala sería utilizar latr
utilidad:tr
traduce un conjunto de caracteres a otro, por lo que simplemente le decimos que traduzca el conjunto de dígitos farsi al conjunto de dígitos latinos.EDITAR : Como señala el usuario @cuonglm. Esto requiere que no sea GNU
tr
, por ejemplo,tr
en una Mac, y también requiere que$LC_CTYPE
esté configurado enen_US.UTF-8
.fuente
en_US.utf8
.