André Laugks: Interpunktionszeichen in UTF-8 convertieren

Hallo!

Ich möchte HTML-Seiten onthefly in UTF-8 umwandeln. Leider habe ich Probleme mit Interpunktionszeichen. Da diese Zeichen nicht zum ISO-8859-1 Umfang gehören, greift die Funktion iconv() nicht. Sind diese Interpunktionszeichen in einem Zeichensatz zusammen gefasst? Auch uft_encode() bringt mich nicht weiter. Laut Doku wandelt es auch nur ISO-8859-1 und UTF-8 um.

  
$string = '<!DOCTYPE html PUBLIC  
 "-//W3C//DTD XHTML 1.0 Transitional//EN"  
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
</head>  
<body>  
ö ´–  
</body>  
</html>';  
  
echo uft_encode($string);  
// bzw:  
echo iconv('ISO-8859-1', 'UTF-8', $string);  

André Laugks

--
Die Frau geht, die Hilti bleibt!
  1. Moin!

    Ich möchte HTML-Seiten onthefly in UTF-8 umwandeln. Leider habe ich Probleme mit Interpunktionszeichen. Da diese Zeichen nicht zum ISO-8859-1 Umfang gehören, greift die Funktion iconv() nicht.

    Wie kriegst du es denn hin, diese Interpunktionszeichen in ISO-8859-1 zu codieren, wenn sie nicht Bestandteil dieses Codierungsschemas sind?

    - Sven Rautenberg

    --
    My sssignature, my preciousssss!
    1. Hallo!

      Wie kriegst du es denn hin, diese Interpunktionszeichen in ISO-8859-1 zu codieren, wenn sie nicht Bestandteil dieses Codierungsschemas sind?

      Ok, sorry das Akut gehört zu ISO-8859-1. IMHO der Gedankenstrich aber nicht. Trotzdem wird mir z.B. das ´ (Akut) im Firefox verschluckt. Im IE wird mir ein Kästchen angezeigt. IMHO gehören Interpunktionszeichen nicht um ISO-8859-1 Zeichenumfang. Deshalb ignoriert sie iconv() und uft_encode(). Der Gedankenstrich wird im Firefox und im IE fehlerhaft angezeigt. Die Browser haben UFT-8 als verwendeten Zeichensatz gesetzt.

      Wenn ich es per Hand codiere, funktioniert es!

      Was ich auch nicht ganz verstehe, oder ist es mal wieder an mir vorbei gegangen wie so vieles: Im Quelltext werden mir die Umlaute und Sonderzeichen normal angezeigt, nicht als Unicode. Ist der IE und der Firefox so freundlich und "wandeln" es mir um? Ich sehe also nicht "&#246;", sondern "ö". Ich meine, früher war das mal alles anders. Da war eh alles besser ;-).

      André Laugks

      --
      Die Frau geht, die Hilti bleibt!
      1. hi,

        Was ich auch nicht ganz verstehe, oder ist es mal wieder an mir vorbei gegangen wie so vieles: Im Quelltext werden mir die Umlaute und Sonderzeichen normal angezeigt, nicht als Unicode. [...] Ich sehe also nicht "&#246;", sondern "ö".

        Warum sollte "ö" in "&#246;" umgewandelt werden?
        iconv() konvertiert von einer Zeichenkodierung in eine andere - aber wieso sollte es in eine nummerische HTML-Notation umwandeln? So etwas würde vielleicht htmlentities() machen (eine entsprechende Translation Table vorausgesetzt).

        Ist der IE und der Firefox so freundlich und "wandeln" es mir um?

        Wenn dein zum Anzeigen benutzter Editor (oder der im FF integrierte) _erkennt_, dass es sich um UTF-8 handelt, stellt er dir dies idR. doch "lesbar" dar.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hallo!

          iconv() konvertiert von einer Zeichenkodierung in eine andere - aber wieso sollte es in eine nummerische HTML-Notation umwandeln? So etwas würde vielleicht htmlentities() machen (eine entsprechende Translation Table vorausgesetzt).

          Ich meine mich zu errinnern, dass uft_encode() in HTML-Notation convertiert hat. Anscheint bin ich aber wohl etwas durcheinander.

          Im Moment frage ich mich auch, wie ich darauf komme, dass mir iconv() Zeichen in HTML-Notation umwandelt.

          Wenn dein zum Anzeigen benutzter Editor (oder der im FF integrierte) _erkennt_, dass es sich um UTF-8 handelt, stellt er dir dies idR. doch "lesbar" dar.

          Kann natürlich sein, dass die Editoren im Gegensatz zu früher einen Fortschritt gemacht haben. Damals ;-) wurden die Zeichen ja auch zerhackt dargetellt und nicht als HTML-Notation.

          Mhhhh....

          André Laugks

          --
          Die Frau geht, die Hilti bleibt!
      2. Moin!

        Wie kriegst du es denn hin, diese Interpunktionszeichen in ISO-8859-1 zu codieren, wenn sie nicht Bestandteil dieses Codierungsschemas sind?

        Ok, sorry das Akut gehört zu ISO-8859-1. IMHO der Gedankenstrich aber nicht. Trotzdem wird mir z.B. das ´ (Akut) im Firefox verschluckt. Im IE wird mir ein Kästchen angezeigt. IMHO gehören Interpunktionszeichen nicht um ISO-8859-1 Zeichenumfang. Deshalb ignoriert sie iconv() und uft_encode().

        Ja, das mag ja sein. Aber du mußt doch die Zeichen irgendwie eingegeben und als ISO-8859-1 abgespeichert haben, sonst kannst du sie doch nicht speichern und anzeigen.

        Der Gedankenstrich wird im Firefox und im IE fehlerhaft angezeigt. Die Browser haben UFT-8 als verwendeten Zeichensatz gesetzt.

        Welches UTF-8-Zeichen ist das? Welches Byte (Zahlenwert) steht in deiner Datei?

        Wenn ich es per Hand codiere, funktioniert es!

        Was heißt "per Hand codieren"?

        Was ich auch nicht ganz verstehe, oder ist es mal wieder an mir vorbei gegangen wie so vieles: Im Quelltext werden mir die Umlaute und Sonderzeichen normal angezeigt, nicht als Unicode.

        Es gibt viele Erscheinungsformen von Zeichenfestlegungen. "Unicode" ist als Beschreibung aber denkbar ungeeignet, weil darunter alleine schon eine ganze Handvoll von Codierungsschemata fallen, die alle unterschiedliche Methoden zur Speicherung des gesamten Unicode-Zeichenvorrats enthalten - und nebenbei gibt es dann auch noch die bekannten Zeichen-Untermengen wie Latin1 (bzw. eben ISO-8859-1), die nur eine Teilmenge der Unicode-Zeichen enthalten.

        Ist der IE und der Firefox so freundlich und "wandeln" es mir um? Ich sehe also nicht "&#246;", sondern "ö". Ich meine, früher war das mal alles anders. Da war eh alles besser ;-).

        Dein Konstrukt &#246; ist eine "numerische Zeichenreferenz", fälschlich gerne auch mal "Nummern-Entity" o.ä. genannt.

        Die Zahl (egal ob dezimal oder hexadezimal) ist die Unicode-Codepoint. Ein Codepoint ist eine Zuordnung von einer Zahl zu einem Zeichen. Der Codepoint für "64" definiert z.B. das @-Zeichen in den Unicode-Tabellen.

        Browser wandeln Entitys (also benannte Zeichen wie &auml;) und numerische Zeichenreferenzen (&#64;) in die entsprechenden Zeichen um (es erscheint also ein ä und ein @-Zeichen).

        Die numerischen Zeichenreferenzen können dabei unabhängig von der aktuellen Zeichencodierung jederzeit jedes existierende Unicode-Zeichen referenzieren. Du kannst damit also auch in einem ISO-8859-1-Text mittendrin Chinesisch schreiben, oder das Euro-Zeichen einfügen (das in ISO-8859-1 auch nicht enthalten ist).

        An diesen Möglichkeiten hat sich seit Bestehen von HTML aber nie etwas geändert. Lediglich war Unicode früher noch nicht so verbreitet, genauso wie das Internet hauptsächlich nur im englischsprachigen Kulturraum verbreitet war, und deshalb Zeichencodierungsprobleme fast nie auftraten, weil die für Englisch notwendigen Zeichen in nahezu jedem Codierungsschema vorkommen und auch immer mit den gleichen Zahlenwerten codiert werden.

        - Sven Rautenberg

        --
        My sssignature, my preciousssss!
        1. Hallo!

          Ja, das mag ja sein. Aber du mußt doch die Zeichen irgendwie eingegeben und als ISO-8859-1 abgespeichert haben, sonst kannst du sie doch nicht speichern und anzeigen.

          Mein Problem ist, wenn es zu ISO-8859-1 gehört, wieso schaft es iconv() oder utf_encode() nicht, mir die Zeichen richtig zu konvertieren?

          Welches UTF-8-Zeichen ist das? Welches Byte (Zahlenwert) steht in deiner Datei?

          Ähhhmmmm... Wie finde ich den das heraus?

          Man man, da wird im Moment eine ganz schöne Baustelle aufgerissen. Mit diesem ganzen "Byte (Zahlenwert)" wollte ich mich lange mal auseinander setzen.

          Wenn ich es per Hand codiere, funktioniert es!

          Was heißt "per Hand codieren"?

          Wenn ich es als nummerische HTML-Notation schreibe.

          Browser wandeln Entitys [...]

          Danke Danke, dass habe ich aber schon lange verstanden was die Browser mit den Entitys machen. ;-)

          André Laugks

          --
          Die Frau geht, die Hilti bleibt!
          1. hi,

            Welches UTF-8-Zeichen ist das? Welches Byte (Zahlenwert) steht in deiner Datei?

            Ähhhmmmm... Wie finde ich den das heraus?

            Betrachte doch die Datei mal mit einem Hex-Editor.

            Wenn ich es per Hand codiere, funktioniert es!

            Was heißt "per Hand codieren"?

            Wenn ich es als nummerische HTML-Notation schreibe.

            Und wo soll da der Zusammenhanf zur "echten" Kodierung eines Zeichens in UTF-8 bestehen?

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            1. Hallo!

              Betrachte doch die Datei mal mit einem Hex-Editor.

              https://forum.selfhtml.org/?t=122187&m=786145

              Und wo soll da der Zusammenhanf zur "echten" Kodierung eines Zeichens in UTF-8 bestehen?

              Gar keiner! Ich bin da ein wenig auf dem Holzweg.

              André Laugks

              --
              Die Frau geht, die Hilti bleibt!
  2. Hallo,

    $string = '<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
    ö ´–
    </body>
    </html>';

    echo uft_encode($string);
    // bzw:
    echo iconv('ISO-8859-1', 'UTF-8', $string);

      
    Das ist widersinnig. Du sagst iconv, dass das Dokument in ISO-8859-1 kodiert ist, weißt aber genau, dass es Zeichen enthält, die nicht mit ISO-8859-1 kodierbar sind? Äh? Was steht denn dann genau im Dokument?  
      
    Meiner Vermutung nach ist es gar nicht in ISO-8859-1 kodiert, sondern in Windows-1252. Dort gibt es das Zeichen – (U+2013), es wird mit 0x96 kodiert. Schau dir mal das Dokument bzw. das PHP-Script in einem Hexeditor an. Wenn du ein Byte 0x96 findest, ist es wohl Windows-1252-kodiert. In ISO-8859-1 steht an der Stelle ein Steuerzeichen.  
      
    In dem Fall müsstest du korrekt iconv('Windows-1252', 'UTF-8', $string) notieren. Ein kleiner Test:  
      
    ~~~php
    <?php  
    function list_bytes ($str) {  
     $i = 0;  
     while (isset($str{$i})) {  
      echo(($io = ord($str{$i})) . ' | 0x' . dechex($io) . "\n");  
      $i++;  
     }  
     echo("\n");  
    }  
      
    list_bytes(iconv('ISO-8859-1', 'UTF-8', "\x96"));  
    list_bytes(iconv('Windows-1252', 'UTF-8', "\x96"));  
    ?>
    

    Ausgabe:
    194 | 0xc2
    150 | 0x96

    226 | 0xe2
    128 | 0x80
    147 | 0x93

    Die erste Bytesequenz ist die UTF-8-Kodierung des Zeichens U+0096. Dies ist wie gesagt ein nicht druckbares Steuerzeichen (welches im übrigen in HTML und XHTML nicht vorkommen darf, wenn ich mich recht entsinne).
    Die zweite Bytesequenz ist die UTF-8-Kodierung des gewünschten Zeichens U+2013.

    Mathias

    1. Hallo!

      Meiner Vermutung nach ist es gar nicht in ISO-8859-1 kodiert, sondern in Windows-1252. [...]

      In dem Fall müsstest du korrekt iconv('Windows-1252', 'UTF-8', $string) notieren. Ein kleiner Test:

      Aaahhhhhh! Leutet mir völlig ein wo Du das hier schreibst.

      Vielen Dank!

      André Laugks

      --
      Die Frau geht, die Hilti bleibt!
    2. Hallo!

      Das ist widersinnig. [...]

      Vollig! Deshalb ja auch die Frage nach dem passenden Charset.

      Meiner Vermutung nach ist es gar nicht in ISO-8859-1 kodiert, sondern in Windows-1252. Dort gibt es das Zeichen – (U+2013), es wird mit 0x96 kodiert.

      Ja, habe ich aufgefunden.

      Nochmals Danke!

      André Laugks

      --
      Die Frau geht, die Hilti bleibt!