In persischen Ziffern ۰۱۲۳۴۵۶۷۸۹
entspricht 0123456789
in europäischen Ziffern.
Wie kann ich persische Zahlen (in UTF-8
) in ASCII konvertieren ?
Zum Beispiel möchte ich ۲۱
werden 21
.
bash
unicode
conversion
بارپابابا
quelle
quelle
echo "۰۱۲۳۴۵۶۷۸۹" | iconv -f UTF-8 -t ascii//TRANSLIT
nicht damiticonv
ist es nur hier, um Zeichen in verschiedenen Codierungen abzubilden, aber dies sind Zeichen (ostarabische Ziffern), die kein Äquivalent in ASCII haben. Sie können sie einfach in etwas Ähnliches konvertieren, aber es ist nur in eine Richtung.iconv
fähig und nicht fähig war. Ich hatte gehofft//TRANSLIT
, dass das nicht helfen würde, aber das tat es nicht.Antworten:
Wir können die Tatsache ausnutzen, dass die UNICODE-Codepunkte der persischen Ziffern fortlaufend sind und von 0 bis 9 geordnet sind :
Das bedeutet, dass die letzte Hex-Ziffer der Dezimalwert ist:
Das macht diese einfache Schleife zu einem Konvertierungswerkzeug:
Verwenden Sie es als:
Beachten Sie, dass dieser Code auch arabische und lateinische Ziffern konvertieren kann (auch wenn gemischt):
quelle
'۰
. Es hätte auch so geschrieben werden können'"۰'
. Der Grund dafür ist, dass printf den UNICODE-Codepunkt angibt, wenn das Argument mit einem einfachen Anführungszeichen'
oder einem doppelten Anführungszeichen beginnt"
. Suchen Sie kurz vor diesem Link nach dem Text "Wenn das führende Zeichen ein einfaches oder doppeltes Anführungszeichen ist"Da es sich um eine feste Anzahl von Zahlen handelt, können Sie dies von Hand tun:
(oder mit
tr
, aber noch nicht GNU tr )Um Ihren
en_US.utf8
Zeichensatzsed
zu erkennen, müssen Sie Ihr Gebietsschema auf (oder besser auf das Gebietsschema, zu dem der Zeichensatz gehört) einstellen.Mit
perl
:quelle
LC_ALL
so eingestellt werden, dass jedes einzelne Unicode-Zeichen auch von als solches betrachtet wirdsed
, oder?tr
genau zu diesem Zweck erfunden ?tr
es darum geht, wie es nicht überall funktioniert. Denken Sie auch daran, dass einige Tools für den Umgang mit Bytes optimiert sind, während andere für den Umgang mit Zeichen optimiert sind. Mit Unicode (insbesondere UTF-8) macht dies einen großen Unterschied.LC_ALL
.LC_ALL
ist auch nicht in meiner Umgebung festgelegt (aberLANG
festgelegt aufen_GB.UTF-8
). Mit dem obigen Code erhalte ich die Fehlermeldung "sed: 1:" y / ۰۱۲۳۴۵۶۷۸۹ / ... ": Transformationszeichenfolgen haben nicht die gleiche Länge".Für Python gibt es die
unidecode
Bibliothek, die solche Konvertierungen im Allgemeinen verwaltet: https://pypi.python.org/pypi/Unidecode .In Python 2:
In Python 3:
Der SO-Thread unter /programming//q/8087381/2261442 könnte verwandt sein.
/ edit: Wie Wander Nauta zeigte in den Kommentaren und wie auf der Unidecode Seite erwähnt , gibt es auch eine Shell - Version
unidecode
(unter/usr/local/bin/
falls installiert überpip
):quelle
unidecode
, das dasselbe wie Ihr Python 3-Snippet ausführt. Sollte einfachecho '۰۱۲۳۴۵۶۷۸۹' | unidecode
funktionieren.pip
es dort.unidecode/util.py
- seltsam, dass Debian es nicht enthält. (Edit: Ah, das Rätsel ist gelöst. Das Debian-Paket ist veraltet und älter als das Hilfsprogramm.)Eine reine Bash-Version:
Habe in meinem Gentoo Rechner getestet und es funktioniert.
Als Schleife ausgeführt, mit der Liste der zu konvertierenden Zeichen (von 0 bis 9):
Und verwendet als:
Ein anderer (eher übertriebener) Weg mit
grep
:quelle
grep
. Tatsächlich verstehe ich diese Zeile nicht und auch nicht, warum Sie sie nicht setzenresult=0
. Sind Sie übervorsichtig, wenn es sich$1
nicht nur um Farsi-Ziffern handelt?number=${number//۱/1}
usw. und würden dasecho
und vermeidengrep
.Da
iconv
dies nicht zu befürchten scheint, wäre die nächste Anlaufstelle die Verwendung destr
Dienstprogramms:tr
Übersetzt einen Zeichensatz in einen anderen, so dass wir ihn einfach anweisen, den Satz der persischen Ziffern in den Satz der lateinischen Ziffern zu übersetzen.EDIT : Als Benutzer @cuonglm weist darauf hin. Dies erfordert Nicht-GNU
tr
, z. B.tr
auf einem Mac, und es erfordert auch, dass auf festgelegt$LC_CTYPE
isten_US.UTF-8
.quelle
en_US.utf8
.