Formattieren von Nicht-7-bit-Strings

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Darii, BlackJack: Ich glaube nicht dass ich das Thema Unicode jetzt für immer los geworden bin! Die momentane Frustration darüber, dass eine einfache Sache wie die Berechnung der Breite einer Zeichenkette mein Fortschritt verhindert, habe ich allerdings überwunden.

Die Datenbank ist in latin1 weil das auch so von MySQL gemeldet wird (steht oben in einem code-Abschnitt). Eines Tages könnte ich versuchen, die Daten mit UTF-8 in MySQL anzulegen. Dann befürchte ich, später mal Probleme bei der Dateneingabe direkt unter MySQL, bzw. mit der Kommunikation mit Flatfiles zu bekommen, das alles bereiche sind, wo es heute problemlos läuft.

Zum Experimentieren um die richtige Lösung zu finden bin ich hoffentlich bei dem nächsten Unicode-Problem bereit.

Breite von "ä": Huch, wenn len("ä") = 2 auch wenn man alles "richtig" eingibt, ist ja komisch. In den Breitengraden aus denen ich komme (Finnland, Schweden usw.) ist "ä" ein (1) Buchstabe und keineswegs ein "zusammengesetztes Zeichen" oder irgendeine Spezialform von "a" (wie es hier südlich vom Ostsee der Fall zu sein scheint). "ä" kommt sortiermäßig auch nach "z" (... xyzåäö). Also würde in diesem Falle die "richtige" Lösung überhaupt nicht die tatsächlich richtige Lösung sein, zumindest aus meiner Sicht (locale).
Darii hat geschrieben:
kajarno hat geschrieben:Also habe ich die Lösung selbst gebastelt, denn eigentlich ist alles was ich brauche eine Funktion, die die *Druckbreite* eines Strings errechnet, anstatt die Speicherbreite (die beim Drucken herzlich egal ist).
Wie BlackJack schon schrieb, lass das lieber und versuch zu verstehen, wie das mit den Zeichenkodierungen funktioniert, sonst wirst du bestimmt bald wieder irgendwelche Probleme kriegen.

Die Druckbreite zu bestimmen ist übrigens wirklich nicht so einfach.

Code: Alles auswählen

>>> ae = unicodedata.normalize("NFD", u"ä")
>>> print ae, len(ae), repr(ae)
ä 2 u'a\u0308'
Ein druckbares Zeichen kann nämlich durchaus aus mehreren Zeichen zusammengesetzt sein.
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

kajarno hat geschrieben:In den Breitengraden aus denen ich komme (Finnland, Schweden usw.) ist "ä" ein (1) Buchstabe und keineswegs ein "zusammengesetztes Zeichen" oder irgendeine Spezialform von "a" (wie es hier südlich vom Ostsee der Fall zu sein scheint).
Das hat nicht sonderlich viel mit locales zu tun, sondern mit dem Unicode-Standard, der eben verschiedene Normalformen definiert. Je nachdem ist ä eben ein Kompisitum aus a und Diaeresis(Combining Diaeresis) oder ein einzelner Buchstabe(a with Diaeresis).
Aber das kann die Doku viel besser als ich: http://docs.python.org/library/unicoded ... .normalize
BlackJack

@kajarno: Was die Datenbank annimmt welche Kodierung sie bekommt, und welche sie tatsächlich bekommt, sind zwei verschiedene Dinge. Und ich denke Du hast da falsche/kaputte Daten in der DB. Du sagtest ja selbst, dass MySQL die Länge auch "falsch" berechnet. Was höchstwahrscheinlich daran liegt, das in der DB die "denkt" Latin1 zu enthalten, tatsächlich UTF-8 drin ist.

Wenn eine Datenbank/Tabelle auf Latin1 eingestellt ist, müssen die Daten auch so kodiert da reingeschrieben werden. Man kann allerdings auch problemlos UTF-8 kodierte Umlaute in so eine Tabelle schreiben, weil das ja in Latin1 keine illegallen Bytefolgen sind. Sie bedeuten halt nur etwas anderes, aber das weis die Datenbanksoftware ja nicht.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

kajarno hat geschrieben:Breite von "ä": Huch, wenn len("ä") = 2 auch wenn man alles "richtig" eingibt, ist ja komisch. In den Breitengraden aus denen ich komme (Finnland, Schweden usw.) ist "ä" ein (1) Buchstabe und keineswegs ein "zusammengesetztes Zeichen" oder irgendeine Spezialform von "a" (wie es hier südlich vom Ostsee der Fall zu sein scheint).
Das mit der Normalform war auch nur ein Beispiel(wenn auch ein wichtiges, denn OSX kodiert seine Dateinamen so und kommt leider mit anders kodierten nicht zurecht). Er gibt im Grunde genommen nur eine sichere Methode herauszufinden wie „breit“ ein String ist: Rendern lassen und gucken was dabei rauskommt. Alles andere führt zwangläufig zu Fehlern.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mach doch mal sowas:

Code: Alles auswählen

MYSQL_ENCODING_VARS = ("character_set_server", "character_set_connection", "character_set_results", "collation_connection",)
for var_name in MYSQL_ENCODING_VARS:
    cursor.execute("SHOW VARIABLES LIKE %s;", (var_name,))
    print var_name, cursor.fetchall()
Ich hab auch einen einfachen Test geschrieben bei dem ich mit unichr() einen Test string in unicode erzeuge. Der wird dann in die Datenbank eingefügt und gleich wieder herraus geholt und mit dem Original verglichen.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten