En números persas, ۰۱۲۳۴۵۶۷۸۹es equivalente a 0123456789en 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//TRANSLITno lo maneja ...iconves 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.iconvera capaz y no capaz de hacer. Esperaba que usarlo me//TRANSLITayudara, 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) parasedreconocer su conjunto de caracteres.Con
perl:fuente
LC_ALLEs necesario configurarlo para que todos los caracteres unicode también sean considerados como tales porsed, ¿verdad?trpara este propósito exacto?trcó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_ALLtampoco está configurado en mi entorno (peroLANGestá 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
unidecodebiblioteca 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
unidecodeque hace lo mismo que su fragmento de Python 3. Soloecho '۰۱۲۳۴۵۶۷۸۹' | unidecodedeberí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$1contenga otras cosas que no sean dígitos farsi?number=${number//۱/1}etc., y evitarían elechoygrep.Como
iconvparece que no puede asimilar esto, el siguiente puerto de escala sería utilizar latrutilidad:trtraduce 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,tren una Mac, y también requiere que$LC_CTYPEesté configurado enen_US.UTF-8.fuente
en_US.utf8.