Länge eines unicode und utf-8 strings falsch

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.
Antworten
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

Hallo Leute,

mein Ziel war, Text mit Konsolenmitteln zu umrahmen, dh. aus

Code: Alles auswählen

Das ist ein Text
sollte

Code: Alles auswählen

+------------------+
| Das ist ein Text |
+------------------+
werden. Eigentlich nicht sonderlich schwierig (dachte ich). Nun aber folgendes:

Code: Alles auswählen

BLA = u"""TExt, der beabsichtigt wüst formatiert ist!

Hier nun etwas mehr Text, um festzustellen, ob dieser auch
    tatsächlich so schön formatiert wird wie erwartet!

    Hier mal ein paar Sonderzeichen, mit AltGr und
    allen Tastaturelementen:
    
    obere Zeile:
      @ ł € ¶ ŧ ← ↓ → ø þ ¨ ~
    mittlere Zeile:
      æ ſ ð đ ŋ ħ ł ˝ ^ `
    untere Zeile:
      | » « ¢ „ “ ” µ · …
    
        
        
    Das ist ein weiterer Absatz, nur um festzustellen, dass auch
        Leer- und Tabulatorzeichen exakt verarbeitet werden.
Noch mal eine Zeile, in welche ein paar Umlaute äöüß eingefügt sind.
    """

ENC = "utf-8"
TAB = u"    "
formatstr = u"{:<%s}" % (74,)
i = 1
for zeile in BLA.split(os.linesep):
    z = zeile.replace("\t", TAB)
    out = u"| %s |" % (formatstr.format(z),)
    print out.encode(ENC) + "<-%s (Zeile %s)" % (len(out),i)
    i += 1
Dies ergab dann unerwarteterweise folgende Ausgabe:

Code: Alles auswählen

| TExt, der beabsichtigt wüst formatiert ist!                                |<-78 (Zeile 1)
|                                                                            |<-78 (Zeile 2)
| Hier nun etwas mehr Text, um festzustellen, ob dieser auch                 |<-78 (Zeile 3)
|     tatsächlich so schön formatiert wird wie erwartet!                   |<-78 (Zeile 4)
|                                                                            |<-78 (Zeile 5)
|     Hier mal ein paar Sonderzeichen, mit AltGr und                         |<-78 (Zeile 6)
|     allen Tastaturelementen:                                               |<-78 (Zeile 7)
|                                                                            |<-78 (Zeile 8)
|     obere Zeile:                                                           |<-78 (Zeile 9)
|       @ ł € ¶ ŧ ← ↓ → ø þ ¨ ~                                              |<-78 (Zeile 10)
|     mittlere Zeile:                                                        |<-78 (Zeile 11)
|       æ ſ ð đ ŋ ħ ł ˝ ^ `                                                  |<-78 (Zeile 12)
|     untere Zeile:                                                          |<-78 (Zeile 13)
|       | » « ¢ „ “ ” µ · …                                                  |<-78 (Zeile 14)
|                                                                            |<-78 (Zeile 15)
|                                                                            |<-78 (Zeile 16)
|                                                                            |<-78 (Zeile 17)
|     Das ist ein weiterer Absatz, nur um festzustellen, dass auch           |<-78 (Zeile 18)
|         Leer- und Tabulatorzeichen exakt verarbeitet werden.               |<-78 (Zeile 19)
| Noch mal eine Zeile, in welche ein paar Umlaute äöüß eingefügt sind.       |<-78 (Zeile 20)
|                                                                            |<-78 (Zeile 21)

Ich sehe gerade, dass die Textausgabe im Code-Abschnitt nicht wie gewollt mittels BBC-Code angezeigt wird. Die Schriftart ist wohl nicht so was wie Courier - irgend eine proportionale Schrift - so kann man den Längenunterschied in den Zeilen leider nicht am Bild erkennen?!? :(

Werde noch ein Bild meiner Konsolenausgabe ins Netz stellen und verlinken, so dass man das besser erkennen kann...

(Kann man die Schriftart irgendwo einstellen, da [pre]...[/pre] nicht funzt?)


Zeile 4 ist, obwohl dessen Länge exakt angegeben wurde, um 2 Zeichen zu kurz??? :shock:

An den Umlauten kann es doch wohl nicht liegen, da diese ja in mehreren Zeilen vorkommen und die Längn dort wie gewollt dargestellt sind. Irgendwie will es mir nicht gelingen den Fehler zu finden. Gestern nicht, heute nicht , morgen... :(

Seht ihr mehr?

Danke im Voraus


-----------------------------
System: openSuse 11.4-78 (Zeile 7)
BlackJack

@sedi: Ich kann das Problem nicht nachvollziehen. Bei mir funktioniert Dein Quelltext wie gewünscht.

Statt `split()` mit `os.linesep` hätte ich die `splitlines()`-Methode verwendet. Und das manuelle hochzählen von `i` solltest Du durch die `enumerate()`-Funktion ersetzen.
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

Danke für die prompte Antwort!

Habe den Fehler nun gefunden:

In dem Text waren *sonderbare* Formatierungen. Die zwei Umlautpunkte wurden auf die nachfolgenden Buchstaben gesetzt. Dies war nur in der fehlerhaft dargestellten Zeile der Fall.

Wie so oft entstehen neue Fragen, wenn alte geklärt wurden:
  • - Wie kann man derartige Buchstaben erzeugen?
    - Und wie kann ich feststellen, dass mein Funktionsargument keine Texte mit solchem Inhalt erhalten hat, da ja dann meine Funktion nicht exakt funktionieren würde?
(Die Zeile, die eine fehlerhafte Ausgabe erzeugte kann ich auch hier nicht ins Forum stellen, da beim Einkopieren die Umlautpunkt wieder korrekt angebracht werden :?: :?: :?: )
BlackJack

@sedi: `len()` zählt nicht die Länge in Zeichen sondern die Anzahl der Unicode-Codepoints. So etwas wie Umlaute oder Accents an einem Zeichen kann man auch mit zwei Codepoints kodieren. So lassen sich Umlautpunkte und Accents auf *jedes* Zeichen anwenden, auch auf solche die keinen eigenen Codepoint für die Kombination haben. Ausserdem gibt es auch Codepoints die keine sichtbaren Zeichen darstellen, wie beispielsweise den „zero width join” der zwischen zwei Zeichen gesetzt wird und sagt, dass die nicht getrennt werden dürfen. Also 100%ig wirst Du so eine Rahmenfunktion nur mit etwas Aufwand erzeugen können, wenn sie wirklich für *alles* funktionieren soll.
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

@Blackjack

Danke - gecheckt


als gelöst markiert!
Antworten