Beim Lesen und Schreiben von verschiedenen Systemen kommt es nicht selten zu Kodierungsproblemen, wenn die Systeme unterschiedliche Gebietsschemata haben. In diesem Beitrag zeige ich Ihnen mehrere Optionen für den Umgang mit solchen Problemen.
Beispiel
Nehmen wir an, Sie haben ein Feld mit Namen und es gibt einen tschechischen Namen "Mořic", der ein r mit Caron enthält, den Sie mit Windows-1252 in eine csv-Datei exportieren müssen1 Kodierung. Dies wird fehlschlagen:
>>> Beispiel = 'Mořic' >>> Beispiel.verschlüsseln('WINDOWS-1252') UnicodeEncodeError: 'charmap' Codec kannt Zeichen verschlüsseln 'u0159' an Position 2: Das Zeichen wird auf
Leider unterstützt Windows-1252 dieses Zeichen nicht, so dass eine Ausnahme ausgelöst wird. Wir brauchen also eine Möglichkeit, solche Kodierungsprobleme zu behandeln.
Kodierungsoptionen
Seit Python 3.32wird der Typ str in Unicode dargestellt. Unicode-Zeichen haben keine Darstellung in Bytes. Das ist die Aufgabe der Zeichenkodierung - eine Abbildung von Unicode-Zeichen auf Bytes. Jede Kodierung handhabt die Abbildung anders, und nicht alle Kodierungen unterstützen alle Unicode-Zeichen, was zu Problemen bei der Konvertierung von einer Kodierung in die andere führen kann. Nur die UTF-Familie unterstützt alle Unicode-Zeichen. Die am häufigsten verwendete Kodierung ist UTF-8, halten Sie sich also nach Möglichkeit an diese.
Mit str.encode haben Sie mehrere Optionen für die Fehlerbehandlung. Die Standardsignatur ist str.encode(encoding="utf-8", errors="strict"). Bei dem Beispiel "Mořic" lauten die Fehleroptionen:
| Fehler Wert | Beschreibung | Ergebnis |
|---|---|---|
strict | Kodierungsfehler lösen einen UnicodeError aus (Standard). | Ausnahme |
ignore | Fehlerhafte Zeichen ignorieren. | Moic |
replace | Ersetzen Sie fehlerhafte Zeichen durch ?. | Mo?ic |
xmlcharrefreplace | Ersetzen Sie fehlerhafte Zeichen durch eine XML-Zeichenreferenz. | Mořic |
backslashreplace | Ersetzen Sie fehlerhafte Zeichen durch eine Escape-Sequenz mit umgekehrtem Schrägstrich. | Mou0159ic |
namereplace | Ersetzen Sie fehlerhafte Zeichen durch N{...} Escape-Sequenz. | MoN{LATIN SMALL LETTER R WITH CARON}ic |
Text-Normalisierung
Eine gute Alternative ist, die Daten zunächst mit unicodedata.normalize zu normalisieren. Der Unicode-Standard definiert einige Zeichen als aus mehreren anderen Zeichen zusammengesetzt. Zum Beispiel ist "ř" zusammengesetzt aus "r"(lateinischer Kleinbuchstabe r (U+0072)) und "ˇ"(Kombinationskaron (U+030C)). Nicht alle Webseiten mit Zeicheninformationen zeigen diese Informationen, aber z.B. diese Seite zeigt die zusammengesetzten Zeichen und Normalisierungsformen an: chars.suikawiki.org/char/0159.
Die Normalisierung kann in vier Formen angewendet werden:
| Normale Form | Vollständiger Name |
|---|---|
| NFD | Normalisierungsform Kanonische Dekomposition |
| NFC | Normalisierungsform Kanonische Komposition |
| NFKD | Normalisierung Form-Kompatibilitäts-Zerlegung |
| NFKC | Normalisierung Form Kompatibilität Zusammensetzung |
Um Unicode-Normalformen zu verstehen, benötigen wir zunächst ein paar Hintergrundinformationen.
Unicode und zusammengesetzte Zeichen
In Unicode werden die Zeichen auf so genannte Codepunkte abgebildet. Jedes Zeichen im Unicode-Universum3 wird durch einen Codepunkt, geschrieben als U+, und vier hexadezimale Ziffern ausgedrückt; z.B. steht U+0061 für ein kleines "a".
Der Unicode-Standard bietet zwei Möglichkeiten zur Angabe von zusammengesetzten Zeichen:
- Zerlegt: als eine Folge von kombinierten Zeichen
- Vorkomponiert: als ein einziges kombiniertes Zeichen
Zum Beispiel wird das Zeichen "ã" (Kleinbuchstabe a mit Tilde) in zerlegter Form als U+0061 (a) U+0303 (˜), oder in vorkomponierter Form als U+00E3 (ã) angegeben.
Zusammensetzung und Zersetzung
Unter Komposition versteht man die Kombination mehrerer Zeichen zu einem einzigen Zeichen, in der Regel ein Grundzeichen und ein oder mehrere Zeichen.4. Die Zerlegung ist der umgekehrte Vorgang: ein zusammengesetztes Zeichen wird in mehrere Zeichen zerlegt.
Bevor wir uns mit der Normalisierung befassen, sollten wir eine Funktion definieren, die die Unicode-Codepunkte für jedes Zeichen in einer Zeichenkette ausgibt:
>>> def Unicodes(String): >>> return ' '.beitreten('U+{:04X}'.Format(ord(c)) für c in String) >>> >>> Beispiel = 'Mořic' >>> drucken(Unicodes(Beispiel)) U+004D U+006F U+0159 U+0069 U+0063
Kanonische und Kompatibilitäts-Äquivalenz
Ein Problem ergibt sich, wenn Zeichen mehrere Darstellungen haben. Zum Beispiel kann das Ångström-Symbol Å (eine Ångström-Einheit entspricht einem Zehnmilliardstel Meter) auf drei Arten dargestellt werden:
U+212B U+00C5 U+0041 U+030A
Wie können wir feststellen, ob Zeichenketten gleich sind, wenn ihre zerlegten Formen unterschiedlich sind? Die Unicode-Äquivalenz wird auf zwei Arten definiert:
- Kanonische Äquivalenz
- Gleichwertigkeit der Kompatibilität
Wenn ein Zeichen aus verschiedenen Codepunkten das gleiche Aussehen und die gleiche Bedeutung hat, wird es als kanonisch äquivalent betrachtet. Zum Beispiel haben alle drei Darstellungen des obigen Ångström-Beispiels das gleiche Aussehen und die gleiche Bedeutung und sind daher kanonisch äquivalent.
Kompatibilitätsäquivalenz ist definiert als eine Folge von Codepunkten, die nur die gleiche Bedeutung haben, aber visuell nicht gleich sind. Zum Beispiel werden Brüche als kompatibel äquivalent betrachtet: ¼ (U+00BC) und 1⁄4 (U+0031 U+2044 U+0034) haben nicht dasselbe visuelle Erscheinungsbild, haben aber dieselbe Bedeutung und sind daher kompatibel äquivalent.
Die Kompatibilitätsäquivalenz wird als schwächere Äquivalenzform und als Teilmenge der kanonischen Äquivalenz betrachtet. Wenn ein Zeichen kanonisch äquivalent ist, ist es auch kompatibilitätsäquivalent, aber nicht andersherum.
Anwendung von Unicode-Normalisierungsformen
Mit diesen Hintergrundinformationen können wir nun zu den Unicode-Normalformen übergehen. Anhand des Beispiels "Mořic" am Anfang können wir eine Normalisierung vornehmen, bevor wir diese Zeichenfolge mit Windows-1252 kodieren:
>>> importieren Unicode-Daten >>> >>> def Unicodes(String): >>> return ' '.beitreten('U+{:04X}'.Format(ord(c)) für c in String) >>> >>> Beispiel = "Mořic" >>> >>> drucken(Unicodes(Beispiel)) U+004D U+006F U+0159 U+0069 U+0063 # 5 Unicode-Codepunkte, also wird das ř in vorkomponierter Form angegeben >>> Beispiel.verschlüsseln("WINDOWS-1252") UnicodeEncodeError: 'charmap' Codec kann nicht verschlüsseln Zeichen 'u0159' in Position 2: Zeichen Karten zu undefiniert> # Windows-1252 kann U+0159 (ř) nicht kodieren. >>> nfd_example = unicodedata.normalisieren("NFD", Beispiel) >>> drucken(Unicodes(nfd_example)) U+004D U+006F U+0072 U+030C U+0069 U+0063 # 6 Unicode-Codepunkte, also wird das ř in zerlegter Form angegeben >>> drucken(nfd_example) Mořic # Python-Shell mit UTF-8-Kodierung zeigt immer noch das r mit Caret an. >>> nfd_example.codieren("WINDOWS-1252") UnicodeEncodeError: 'charmap' Codec kann nicht verschlüsseln Zeichen 'u030c' in Position 3: Zeichen Karten zu undefiniert> # Windows-1252 kann jetzt U+0072 (r) kodieren, aber nicht U+030C (ˇ) >>> drucken(nfd_example.codieren('WINDOWS-1252', 'ignorieren')) Moralische # Windows-1252 erfolgreich kodiert und U+030C (ˇ) ignoriert.
Das war's! Mit unicodedata.normalize("NFD", "Mořic").encode('WINDOWS-1252', 'ignore') können wir zuerst normalisieren und dann Windows-1252 kodieren, wobei die unbekannten Zeichen für Windows-1252 ignoriert werden, was zu Moric führt. Ich mag diese Alternative, normalerweise sind die Leute damit einverstanden, da es die Daten nicht zu sehr vermischt und sie lesbar bleibt.
Verbessern Sie Ihre Python-Kenntnisse, lernen Sie von den Experten!
Bei GoDataDriven bieten wir eine Vielzahl von Python-Kursen für Anfänger und Experten an, die von den besten Fachleuten auf diesem Gebiet unterrichtet werden. Kommen Sie zu uns und verbessern Sie Ihr Python-Spiel:
- Python Essentials - Ideal, wenn Sie gerade erst mit Python anfangen.
- Data Science with Python Foundation - Möchten Sie den Schritt von der Datenanalyse und -visualisierung zu echter Datenwissenschaft machen? Dies ist der richtige Kurs.
- Advanced Data Science with Python - Lernen Sie, Ihre Modelle wie ein Profi zu produzieren und Python für maschinelles Lernen zu verwenden.
Referenzen
- Das absolute Minimum, das jeder Softwareentwickler unbedingt über Unicode und Zeichensätze wissen muss - keine Ausreden
- Eine Implementierung der Unicode-Normalisierung
- Canon Kompatibilität Äquivalenz
- wie python unicode macht
- Windows-1252 war der erste Standardzeichensatz in Microsoft Windows und daher werden Sie ihn in vielen älteren Windows-Systemen finden. Der Standard für Windows-Systeme ist heute UTF-16 .
-
Vor Python 3.3 war
strein Byte-String (eine Folge von Bytes in einer bestimmten Kodierung, standardmäßig ASCII) undunicodeein Unicode-String. - Genauer gesagt ist das "Unicode-Universum" die Unicode-Zeichendatenbank (Unicode Character Database, UCD), die alle Unicode-Zeichen sowie deren Eigenschaften und Metadaten enthält.
- Unicode kategorisiert die Zeichen. Jede Kategorie wird durch eine Abkürzung aus zwei Buchstaben bezeichnet, wobei der erste ein Großbuchstabe und der zweite ein Kleinbuchstabe ist. Der Großbuchstabe steht für die Hauptkategorie, der Kleinbuchstabe für die Nebenkategorie. Die Hauptkategorie für Marken ist "M" .
Unsere Ideen
Weitere Blogs
Contact



