Anzeigebreite von Unicode-Strings in Python [duplizieren]

Diese Frage hat hier bereits eine Antwort:

Normalizing Unicode 2 Antworten

Wie kann ich die Anzeigebreite einer Unicode-Zeichenfolge in Python 3.x bestimmen? Gibt es eine Möglichkeit, diese Informationen zu verwenden, um diese Zeichenfolgen an @ auszurichtestr.format()?

Motivierendes Beispiel: Drucken einer Tabelle mit Zeichenfolgen auf der Konsole. Einige der Zeichenfolgen enthalten Nicht-ASCII-Zeichen.

>>> for title in d.keys():
>>>     print("{:<20} | {}".format(title, d[title]))

    zootehni-           | zooteh.
    zootekni-           | zootek.
    zoothèque          | zooth.
    zooveterinar-       | zoovet.
    zoovetinstitut-     | zoovetinst.
    母                   | 母母

>>> s = 'è'
>>> len(s)
    2
>>> [ord(c) for c in s]
    [101, 768]
>>> unicodedata.name(s[1])
    'COMBINING GRAVE ACCENT'
>>> s2 = '母'
>>> len(s2)
    1

Wie man sieht,str.format() nimmt einfach die Anzahl der Codepunkte in der Zeichenkette len(s)) als Breite, was zu verzerrten Spalten in der Ausgabe führt. Durchsuchen desunicodedata Modul, ich habe keine Vorschläge für eine Lösung gefunden.

Unicode-Normalisierung kann das Problem für è beheben, nicht jedoch für asiatische Zeichen, die häufig eine größere Anzeigebreite haben. In ähnlicher Weise existieren Unicode-Zeichen mit der Breite Null (z. B. ein Raum mit der Breite Null, um Zeilenumbrüche innerhalb von Wörtern zuzulassen). Sie können diese Probleme nicht mit der Normalisierung umgehen. Schlagen Sie daher nicht vor, "Ihre Zeichenfolgen zu normalisieren".

Bearbeiten Informationen zur Normalisierung hinzugefügt.

Edit 2: In meinem Originaldatensatz sind auch einige europäische Kombinationszeichen enthalten, die auch nach der Normalisierung keinen einzigen Codepunkt ergeben:

    zwemwater     | zwemw.
    zwia̢z-       | zw.

>>> s3 = 'a\u0322'   # The 'a + combining retroflex hook below' from zwiaz
>>> len(unicodedata.normalize('NFC', s3))
    2

Antworten auf die Frage(1)

Ihre Antwort auf die Frage