En chiffres persans, ۰۱۲۳۴۵۶۷۸۹
équivaut à 0123456789
des chiffres européens.
Comment convertir le nombre persan (in UTF-8
) en ASCII?
Par exemple, je veux ۲۱
devenir 21
.
bash
unicode
conversion
بارپابابا
la source
la source
echo "۰۱۲۳۴۵۶۷۸۹" | iconv -f UTF-8 -t ascii//TRANSLIT
ça ne le gère pas ...iconv
juste ici pour mapper des caractères dans différents encodages, mais ce sont des caractères (chiffres arabes orientaux) qui n'ont pas d'équivalent en ASCII, vous pouvez simplement les convertir en quelque chose d'assez similaire mais c'est à sens unique.iconv
était capable et pas capable de le faire. J'espérais que cette utilisation//TRANSLIT
aiderait, mais ce n'est pas le cas.Réponses:
On peut profiter du fait que le point de code UNICODE des chiffres persans est consécutif et ordonné de 0 à 9 :
Cela signifie que le dernier chiffre hexadécimal EST la valeur décimale:
Cela fait de cette boucle simple un outil de conversion:
L'utiliser comme:
Notez que ce code pourrait également convertir des chiffres arabes et latins (même s'ils sont mélangés):
la source
'۰
. Il aurait pu être écrit aussi comme'"۰'
. La raison en est que printf donnera le point de code UNICODE si l'argument commence par un guillemet simple'
ou un guillemet double"
. Recherchez un peu avant ce lien le texte "Si le premier caractère est un guillemet simple ou double"Puisqu'il s'agit d'un ensemble fixe de nombres, vous pouvez le faire à la main:
(ou en utilisant
tr
, mais pas encore GNU tr )La définition de votre locale
en_US.utf8
(ou mieux la locale à laquelle appartient le jeu de caractères) est nécessaire poursed
reconnaître votre jeu de caractères.Avec
perl
:la source
LC_ALL
est nécessaire pour que tous les caractères Unicode soient également considérés comme tels parsed
, non?tr
dans ce but précis?tr
comment cela ne fonctionne pas partout. Gardez également à l'esprit que certains outils sont optimisés pour traiter les octets tandis que d'autres sont pour traiter les caractères, avec Unicode (en particulier UTF-8), cela fait une énorme différence.LC_ALL
.LC_ALL
n'est pas non plus défini dans mon environnement (maisLANG
est défini suren_GB.UTF-8
). Avec le code ci-dessus, j'obtiens l'erreur "sed: 1:" y / ۰۱۲۳۴۵۶۷۸۹ / ... ": les chaînes de transformation ne sont pas de la même longueur".Pour Python, il existe une
unidecode
bibliothèque qui gère de telles conversions en général: https://pypi.python.org/pypi/Unidecode .En Python 2:
En Python 3:
Le thread SO à /programming//q/8087381/2261442 peut être lié.
/ edit: Comme Wander Nauta l'a souligné dans les commentaires et comme mentionné sur la page Unidecode, il existe également une version shell de
unidecode
(sous/usr/local/bin/
si installée surpip
):la source
unidecode
qui fait la même chose que votre extrait Python 3. Devrait justeecho '۰۱۲۳۴۵۶۷۸۹' | unidecode
fonctionner.pip
c'est là.unidecode/util.py
- étrange que Debian ne l'inclue pas. (Edit: Ah, mystère résolu. Le paquet Debian est obsolète et plus ancien que l'utilitaire.)Une version pure bash:
J'ai testé sur ma machine Gentoo et ça marche.
Fait en boucle, compte tenu de la liste des caractères (de 0 à 9) à convertir:
Et utilisé comme:
Une autre façon (plutôt exagérée) d'utiliser
grep
:la source
grep
. En fait, je ne comprends pas cette ligne, ni pourquoi vous ne définissez pasresult=0
. Êtes-vous trop prudent au cas où il$1
contiendrait autre chose que des chiffres farsi?number=${number//۱/1}
etc., et auraient évité leecho
etgrep
.Puisqu'il
iconv
ne semble pas y avoir de problème, le prochain port d'escale serait d'utiliser l'tr
utilitaire:tr
traduit un ensemble de caractères en un autre, nous lui demandons donc simplement de traduire l'ensemble de chiffres farsi en ensemble de chiffres latins.EDIT : Comme le souligne l'utilisateur @cuonglm. Cela nécessite non-GNU
tr
, par exempletr
sur un Mac, et cela nécessite également qu'il$LC_CTYPE
soit défini suren_US.UTF-8
.la source
en_US.utf8
.