Robert: UTF-8 in ISO-8859-1 plus numerische Zeichenreferenzen wandeln

Hallöle,

aus einer Datenbank bekomme ich UTF-8 Strings mit vielen verschiedenen Zeichen, so daß kein anderes Encoding in der Datenbank sinnvoll ist - außerdem wird die Datenbank noch von anderer (Fremd-)Software benutzt, so daß eine Änderung nicht möglich wäre.

Die HTML-Ausgabe zum Client muß mit ISO-8859-1-Encoding erfolgen (daran kann ich leider nichts ändern - wenn's nach mir ginge, würde ich dem Client UTF-8 schicken).

Jetzt muß ich also die UTF-8-Zeichen umwandeln.
Ok, die Funktion utf8_decode existiert.
Aber: die reicht ja nicht, die wandelt ja nur die UTF-8-Zeichen um, die auch in ISO-8859-1 existieren.
Dann blieben aber noch Zeichen übrig, die nicht in ISO-8859-1 existieren, also hilft mir utf8_decode nicht.

Auch htmlentities() hilft mir nicht, denn in der Datenbank sind Zeichen, für die es keine named entities in HTML gibt.

Gibt es in PHP irgendeine Methode, die mir alle UTF-8-Zeichen, die nicht in ISO-8859-1 enthalten sind (oder von mir aus auch alle, die nicht in US-ASCII enthalten sind) in numerische Zeichenreferenzen (  usw.) umwandelt?

Vielen Dank im Voraus,

cu,
Robert

  1. Hallo Robert,

    Gibt es in PHP irgendeine Methode, die mir alle UTF-8-Zeichen, die nicht in ISO-8859-1 enthalten sind (oder von mir aus auch alle, die nicht in US-ASCII enthalten sind) in numerische Zeichenreferenzen (  usw.) umwandelt?

    Dieses Tool macht das mit Javascript, vielleicht hilft Dir das als Anregung.

    Gruß aus Köln-Ehrenfeld,

    Elya

    1. Hallo,

      Dieses Tool macht das mit Javascript, vielleicht hilft Dir das als Anregung.

      Das scheitert in PHP aber an der nicht vorhandenen Funktion String.charCodeAt() ;-)). Aber die hat Christian ja jetzt indirekt vorgegeben.

      viele Grüße

      Axel

      1. Hallo Axel,

        Das scheitert in PHP aber an der nicht vorhandenen Funktion String.charCodeAt() ;-)). Aber die hat Christian ja jetzt indirekt vorgegeben.

        Stimmt natürlich ;-) Bei der Gelegenheit kann ich mich in diesem utf-8-Thread gleich bei Dir und CK für die Hilfe in meinem utf-8-Thread bedanken, mit Eurer und molilys Hilfe hab ich mein Problem lösen können, die Erleuchtung kam leider erst, nachdem der Thread schon im Archiv war. Ich habe CKs ord-Funktionen kombiniert mit den mb-Funktionen und ein brauchbares Ergebnis erzielt.

        Gruß aus Köln-Ehrenfeld,

        Elya

        1. 你好 Elya,

          [...] </archiv/2005/3/t104162/#m642038> [...]

          Darf man fragen, wofuer du das eigentlich gebraucht hast?

          再见,
          克里斯蒂安

          --
          Das Leben ist wie ein Kartenspiel: was dir gegeben wurde, ist vorbestimmt. Doch wie du damit spielst, ist deine Entscheidung.
          1. Hallo Christian,

            Darf man fragen, wofuer du das eigentlich gebraucht hast?

            ich wußte, daß ich das noch rauslassen müßte ,-) - Вот викириллица

            Nochmal danke für Deine Hilfe.

            Gruß aus Köln-Ehrenfeld,

            Elya

            1. 你好 Elya,

              Darf man fragen, wofuer du das eigentlich gebraucht hast?
              ich wußte, daß ich das noch rauslassen müßte ,-) - Вот викириллица

              Ahjo, nice :)

              Nochmal danke für Deine Hilfe.

              Nicht dafuer, wenn ich keinen Bock haette zu helfen wuerd ich hier nicht
              lesen *g*

              再见,
              克里斯蒂安

              --
              <zentrum> wie war noch mal die option in make.conf fuer das benutzen von pipes um das compile zu beschluenigen?
              <CK1> CFLAGS="-pipe"
              <torsten> Oder man frage einen Gentooer seiner Wahl, wie man 2 km Compilerswitches fuer seine CPU hinbekommt ;)
            2. Hallo zusammen,

              Darf man fragen, wofuer du das eigentlich gebraucht hast?
              ich wußte, daß ich das noch rauslassen müßte ,-) - Вот викириллица

              wie schön, daß hier mal alle Freunde von utf-8 versammelt sind. Verratet mir doch mal eins: wie sucht Ihr nicht-case-senitiv in utf-8, also z.B. ein ä als [äÄ]? ...Achso: es geht um DBs, die keine multibyte-Unterstützung haben.

              Gruß, Andreas

              --
              SELFFORUM - hier werden Sie geholfen,
              auch in Fragen zu richtiges Deutsch
              1. Hallo,

                wie schön, daß hier mal alle Freunde von utf-8 versammelt sind. Verratet mir doch mal eins: wie sucht Ihr nicht-case-senitiv in utf-8, also z.B. ein ä als [äÄ]? ...Achso: es geht um DBs, die keine multibyte-Unterstützung haben.

                Du meinst, UTF-8 transformierte Octet-Streams stehen als Feldinhalte in Text-Feldern von Datenbanken, die kein UTF-8 unterstützen?

                Dann sucht man, wenn Du SELECT ... WHERE meinst, nach Inhalten mit Zeichen außerhalb US-ASCII nicht-case-senitiv in diesen PseudoStrings genau so wie case-senitiv, nämlich gar nicht, weil es nicht geht ;-)).

                Wenn im Feldinhalt "Höhe" als "48c3b66865" steht, Du aber nur WHERE feld = "Höhe" eingeben kannst, und Höhe eben in ISO-8859-1 "48f66865" ist, dann kann dort nichts übereinstimmen.

                Du hast keine Chance, nutze sie ;-)). Man könnte, wenn die Datenbank das anbietet, mit WHERE feld = "H".concat(0xc3b6).concat("he") suchen. Oder man könnte mit Hilfe des ersten Teils der Funktion von Christian, wo es um Zwei-Octet-UTF-8, beginnend mit c<0xe0 geht,  die UTF-8-Octetstreams micht in Entities, sondern in 1-Byte-Hex-Werte umwandeln. Das würde dann in Teilen ISO-8859-1 entsprechen und aus "c3b6" würde "f6". Diese Lösung wäre aber nur für ISO-8859-1-Sonderzeichen geeignet. ISO-8859-2-Sonderzeichen würden falsche Resultate bringen.

                viele Grüße

                Axel

                1. Hi,

                  Du meinst, UTF-8 transformierte Octet-Streams...?

                  wenn die so heißen - ja. Also es steht nicht, wie Du weiter unten beschreibst Hex-Codiert, sondern utf-8-codiert byte für byte quasi als latin-1 geschrieben, also aus ä wird ä und aus Ä wird Ä.

                  stehen als Feldinhalte in Text-Feldern von Datenbanken, die kein UTF-8 unterstützen?

                  genau, in MySQL 3.23 bzw. 4.0.x ... jaja, vielleicht sollte ich mich mal mit Version 4.1 beschäftigen ;-) - trau mich aber nicht.

                  Wenn im Feldinhalt "Höhe" als "48c3b66865" steht, Du aber nur WHERE feld = "Höhe" eingeben kannst, und Höhe eben in ISO-8859-1 "48f66865" ist, dann kann dort nichts übereinstimmen.

                  natürlich nicht so. Wenn das Suchformular ä als utf-8 abschickt, dann wird die DB schon nach ö gefragt. Das geht ja auch, aber Ä wäre eben eine ganz andere Bytefolge und da bräuchte man ja endlos Tabellen, welch utf-8 Zeichen als Gross-/klein zusammengehören.

                  Du hast keine Chance, nutze sie ;-)). Man könnte, wenn die Datenbank das anbietet, mit WHERE feld = "H".concat(0xc3b6).concat("he") suchen. Oder man könnte mit Hilfe des ersten Teils der Funktion von Christian, wo es um Zwei-Octet-UTF-8, beginnend mit c<0xe0 geht,  die UTF-8-Octetstreams micht in Entities, sondern in 1-Byte-Hex-Werte umwandeln.

                  na, da kann ich auch bei ISO bleiben :-)

                  btw.: ist es in anderen Sprachen eigentlich auch so, daß es zwingend zusammengehörende Gross-/kleinVersionen von den Buchstaben gibt? Also, wie in Latin-1 eben ä und Ä zusammengehören und in MySQL ja auch nicht-case-Sensitiv im iso-Modus beide gefunden werden. Und kann MySQL 4.1 das erkennen?

                  Gruß, Andreas

                  --
                  SELFFORUM - hier werden Sie geholfen,
                  auch in Fragen zu richtiges Deutsch
                  1. 你好 Andreas,

                    btw.: ist es in anderen Sprachen eigentlich auch so, daß es zwingend
                    zusammengehörende Gross-/kleinVersionen von den Buchstaben gibt?

                    Nein, in laengst nicht allen. Das japanische Schrift-System z. B. kennt
                    keine Gross- und Kleinschreibung, und die Lateiner kannten eigentlich auch
                    keine Unterscheidung. Die haben einfach drauf losgeschrieben, in
                    Grossbuchstaben, und haben ab und zu mal einen Punkt gemacht. Komma? Wasn
                    das? ;-)

                    再见,
                    克里斯蒂安

                    --
                    Fortune: But Captain -- the engines can't take this much longer!
                  2. Hallo,

                    Also es steht nicht, wie Du weiter unten beschreibst Hex-Codiert, sondern utf-8-codiert byte für byte quasi als latin-1 geschrieben, also aus ä wird ä und aus Ä wird Ä.

                    Was meinst Du mit _nicht_ Hex-Codiert? Im Speicher, egal wo, stehen Bits, diese bilden Oktets z.B. "01001000", das ist 0x48 und das ist in US-ASCII ein "H".

                    Das "ä" in UTF-8 ist 0xc3a4. Das wird in ISO-8859-1 als "ä" dargestellt. Das, was Du beschreibst, ist also das, was ich beschrieb ;-)).

                    Wenn im Feldinhalt "Höhe" als "48c3b66865" steht, Du aber nur WHERE feld = "Höhe" eingeben kannst, und Höhe eben in ISO-8859-1 "48f66865" ist, dann kann dort nichts übereinstimmen.
                    natürlich nicht so. Wenn das Suchformular ä als utf-8 abschickt, dann wird die DB schon nach ö gefragt.

                    Aha, also so wie bei feld = "H".concat(0xc3b6).concat("he") für "Höhe", nur anders geschrieben, eben "Höhe".

                    Das geht ja auch, aber Ä wäre eben eine ganz andere Bytefolge und da bräuchte man ja endlos Tabellen, welch utf-8 Zeichen als Gross-/klein zusammengehören.

                    Ja, das bräuchte man wohl.

                    Du hast keine Chance, nutze sie ;-)). Man könnte, wenn die Datenbank das anbietet, mit WHERE feld = "H".concat(0xc3b6).concat("he") suchen. Oder man könnte mit Hilfe des ersten Teils der Funktion von Christian, wo es um Zwei-Octet-UTF-8, beginnend mit c<0xe0 geht,  die UTF-8-Octetstreams micht in Entities, sondern in 1-Byte-Hex-Werte umwandeln.
                    na, da kann ich auch bei ISO bleiben :-)

                    Richtig, besser wäre auf eine Speicherung in einer Umgebung mit UTF-8-Unterstützung zu setzen, egal ob Datenbank oder nicht. UTF-8 im HTML-Formular lohnt sich nur, wenn die gesamte verarbeitende und speichernde Software auch damit umgehen kann.

                    zusammengehörende Gross-/kleinVersionen von den Buchstaben

                    Gibt es die für die Computerspeicherung denn in US-ASCII bzw. ISO-8859-1? Die Möglichkeit der case insensitiven Suche basiert auf der Festlegung, dass die kleinen Buchstaben jeweils "Grossbuchstabe"+0x20 codiert sind.
                    A = 0x41 = 01000001, a = 0x61 01100001, ...
                    P = 0x50 = 01010000, p = 0x70 01110000, ...
                    Ä = 0xC4 = 11000100, ä = 0xE4 11100100, ...
                                 ^                  ^ Dieses Bit ist das "case-Gen ;-)", das muss beim Vergleich nur ausgeblendet werden.

                    Ob das bei UTF-8 noch genau so einfach geht? Bei dem UTF-8, welches für die Zeichen aus ISO-8859-1 zuständig ist, sollte es das eigentlich.

                    viele Grüße

                    Axel

                    1. Hallo,

                      zusammengehörende Gross-/kleinVersionen von den Buchstaben
                      A = 0x41 = 01000001, a = 0x61 01100001, ...
                      P = 0x50 = 01010000, p = 0x70 01110000, ...
                      Ä = 0xC4 = 11000100, ä = 0xE4 11100100, ...
                                   ^                  ^ Dieses Bit ist das "case-Gen ;-)", das muss beim Vergleich nur ausgeblendet werden.

                      Ob das bei UTF-8 noch genau so einfach geht? Bei dem UTF-8, welches für die Zeichen aus ISO-8859-1 zuständig ist, sollte es das eigentlich.

                      Nach nochmaliger Betrachtung unter Berücksichtigung der Code-Map http://old.no/charmap/iso-8859-1.html kann man wohl folgendes vermuten:

                      1. Normalerweise sollte die nicht casesensitive Suche auch bei UTF-8
                      Ä = 0xc384, ä = 0xc3a4
                      Ö = 0xc396, ö = 0xc3b6
                      Ü = 0xc39c, ü = 0xc3bc
                      noch funktionieren, weil sich der Unterschied immer noch nur in diesem einen bestimmten Bit zeigt. Offensichtlich ist es aber so, dass die Vergleichsroutinen dieses Bit nicht _immer_ ignorieren, was klar wird, wenn man bedenkt, dass sonst auch nicht zwischen
                      ! = 0x21 = 00100001 und A = 0x41 = 01000001
                      2 = 0x32 = 00110010 und R = 0x52 = 01010010
                                   ^                       ^
                      usw. unterschieden werden könnte. Deshalb wird die "Verwandschaft" zwischen
                      Ä = 0xc384 = ...10000100 und ä = 0xc3a4 = ...10100100
                                        ^                            ^
                      nicht erkannt. In diesem Code-Bereich wird einfach das case-Bit nicht mehr ausgeblendet. Das dies aber eben _in_ den Vergleichsroutinen der Software passiert, wird man daran nicht viel ändern können.

                      viele Grüße

                      Axel

    2. Hallöle,

      Dieses Tool macht das mit Javascript, vielleicht hilft Dir das als Anregung.

      Nicht wirklich - da dort nicht eine Sammlung von UTF-8 bytes als Eingabe vorkommt, sondern direkt die Unicode-Codepoints.

      Trotzdem Danke.

      cu,
      Robert

  2. echo $begrueszung;

    Gibt es in PHP irgendeine Methode, die mir alle UTF-8-Zeichen, die nicht in ISO-8859-1 enthalten sind (oder von mir aus auch alle, die nicht in US-ASCII enthalten sind) in numerische Zeichenreferenzen (&#160; usw.) umwandelt?

    iconv oder recode sollten dir helfen

    echo "$verabschiedung $name";

    1. Hallöle,

      echo $begrueszung;

      warum eigentlich begrue_sz_ung?
      Üblicherweise wird das ß, wenn nicht vorhanden, durch ss ersetzt, nicht durch sz.

      iconv oder recode sollten dir helfen

      Nicht wirklich - bei den Funktionen krieg ich die Meldung, daß ich nichtdefinierte Funktionen aufrufe.

      Trotzdem danke, gut zu wissen, daß es theoretisch sowas gibt - nur auf dem betroffenen Server fehlt das.

      cu,
      Robert

  3. 你好 Robert,

    Gibt es in PHP irgendeine Methode, die mir alle UTF-8-Zeichen, die nicht
    in ISO-8859-1 enthalten sind (oder von mir aus auch alle, die nicht in
    US-ASCII enthalten sind) in numerische Zeichenreferenzen (&#160; usw.)
    umwandelt?

    AFAIK gibts sowas nicht eingebaut, aber es geht recht einfach:

      
    function utf8_to_usascii_with_entities($str) {  
      $length = strlen($str);  
      $result = '';  
      
      for($i=0;$i<$length;) {  
        $c = ord($str{$i});  
      
        if($c < 0x80) {  
          $result .= $str{$i};  
          $i += 1;  
        }  
        elseif($c < 0xc2) return NULL;  
        elseif($c < 0xe0) {  
          if($length - $i < 2) return NULL;  
          if(!((ord($str{$i+1}) ^ 0x80) < 0x40)) return NULL;  
          $num = (($c & 0x1f) << 6) | (ord($str{$i+1}) ^ 0x80);  
          $result .= '&#'.$num.';';  
          $i += 2;  
        }  
        elseif($c < 0xf0) {  
          if($length - $i < 3) return NULL;  
          if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && ($c >= 0xe1 || ord($str{$i+1}) >= 0xa0))) return NULL;  
      
          $num = (($c & 0x0f) << 12) | ((ord($str{$i+1}) ^ 0x80) << 6) | (ord($str{$i+2}) ^ 0x80);  
          $result .= '&#'.$num.';';  
          $i += 3;  
        }  
        elseif($c < 0xf8) {  
          if($length - $i < 4) return NULL;  
          if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && (ord($str{$i+3}) ^ 0x80) < 0x40 && ($c >= 0xf1 || ord($str{$i+1} >= 0x90)))) return NULL;  
      
          $num = (($c & 0x07) << 18) | ((ord($str{$i+1}) ^ 0x80) << 12) | ((ord($str{$i+2}) ^ 0x80) << 6) | ($str{$i+3} ^ 0x80);  
          $result .= '&#'.$num.';';  
          $i += 4;  
        }  
        elseif($c < 0xfc) {  
          if($length - $i < 5) return NULL;  
          if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && (ord($str{$i+3}) ^ 0x80) < 0x40 && (ord($str{$i+4}) ^ 0x80) < 0x40 && ($c >= 0xf9 || ord($str{$i+1}) >= 0x88))) return NULL;  
      
          $num = (($c & 0x03) << 24) | ((ord($str{$i+1}) ^ 0x80) << 18) | ((ord($str{$i+2}) ^ 0x80) << 12) | ((ord($str{$i+3}) ^ 0x80) << 6) | (ord($str{$i+4}) ^ 0x80);  
          $result .= '&#'.$num.';';  
          $i += 5;  
        }  
        elseif($c < 0xfe) {  
          if($length - $i < 6) return NULL;  
          if(!((ord($str{$i+1}) ^ 0x80) < 0x40 && (ord($str{$i+2}) ^ 0x80) < 0x40 && (ord($str{$i+3}) ^ 0x80) < 0x40 && (ord($str{$i+4}) ^ 0x80) < 0x40 && (ord($str{$i+5}) ^ 0x80) < 0x40 && ($c >= 0xfd || $str{$i+1} >= 0x84))) return NULL;  
      
          $num = (($c & 0x01) << 30) | ((ord($str{$i+1}) ^ 0x80) << 24) | ((ord($str{$i+2}) ^ 0x80) << 18) | ((ord($str{$i+3}) ^ 0x80) << 12) | ((ord($str{$i+4}) ^ 0x80) << 6) | (ord($str{$i+5}) ^ 0x80);  
          $result .= '&#'.$num.';';  
          $i += 6;  
        }  
        else return NULL;  
      }  
      
      return $result;  
    }  
    
    

    Die Funktion wandelt alles, was nicht us-ascii ist, um in &#<nr>; -- die
    ISO-8859-1-Unterstuetzung musst du selber bauen.

    再见,
    克里斯蒂安

    --
    Ihr wisst nicht, wie man den Menschen dient. Wie sollt ihr wissen, wie man den Goettern dienen soll?
    1. Hallöle,

      AFAIK gibts sowas nicht eingebaut, aber es geht recht einfach:

      Naja, sicher nicht übermäßig kompliziert, aber als "einfach" würd ich das nicht mehr bezeichnen.

      Hattest Du die Funktion schon fertig?
      Oder hast Du die mal schnell geschrieben?

      Zumindest für alle die Zeichen, die jetzt in meinen Testfällen vorkamen, funktioniert die Umsetzung.

      Vielen Dank!

      cu,
      Robert

      1. 你好 Robert,

        Hattest Du die Funktion schon fertig?
        Oder hast Du die mal schnell geschrieben?

        Nein, die habe ich jetzt gerade geschrieben.

        Zumindest für alle die Zeichen, die jetzt in meinen Testfällen vorkamen,
        funktioniert die Umsetzung.

        Die funktioniert ziemlich sicher fuer alle Zeichen :)

        再见,
        克里斯蒂安

        --
        Death is God's way of telling you not to be such a wise guy.
      2. Hallo,

        Naja, sicher nicht übermäßig kompliziert, aber als "einfach" würd ich das nicht mehr bezeichnen.

        Noch ein wenig Hintergrundinformationen: http://forum.de.selfhtml.org/archiv/2005/3/t104162/#m642038.

        viele Grüße

        Axel

    2. Hallöle nochmal,

      hab noch was vergessen:

      Die Funktion wandelt alles, was nicht us-ascii ist, um in &#<nr>; -- die ISO-8859-1-Unterstuetzung musst du selber bauen.

      Nicht notwendig - entscheidend ist ja nur, daß alle Zeichen außerhalb von ISO-8859-1 codiert sind, ob einige der Zeichen innerhalb von ISO-8859-1 auch kodiert sind, ist ziemlich wurscht.

      cu,
      Robert

    3. Heißa, Christian,

      Die Funktion wandelt alles, was nicht us-ascii ist, um in &#<nr>; -- die
      ISO-8859-1-Unterstuetzung musst du selber bauen.

      Ungefähr so hatte ich das damals auch gemacht, jedoch ist es sehr rechenaufwändig, jedes Zeichen einzeln zu überprüfen. Bei großen Dateien dauerte die Berechnung auf unserem 133-MHz-Server teilweise zwei Minuten. Also beschloss ich, das Ganze etwas einfacher zu lösen, und löste die Hex-Werte auf, multiplizierte aus und kam irgendwann auf den folgenden Code aus regulären Ausdrücken, wobei die großen Seiten nur noch zwei Sekunden zu berechnen brauchten.

      function utf8_htmlentities($string, $mkentities=false, $hex=true)  
      {  
        if($hex)  
          $rep = array("'&#x'.dechex(", ").';'");  
        else  
          $rep = array("'&#'.(", ").';'");  
        
        if($mkentities) /* Auch ASCII-Zeichen durch HTML-Entities maskieren */  
          $string = preg_replace("/[\\x0-\\x80]/e", $rep[0]."ord('$0')".$rep[1], $string);  
        
        $string = preg_replace("/([\\xc0-\\xdf])([\\x80-\\xbf])/e", $rep[0]."64*ord('$1')+ord('$2')-12416".$rep[1], $string);  
        $string = preg_replace("/([\\xe0-\\xef])([\\x80-\\xbf])([\\x80-\\xbf])/e", $rep[0]."4096*ord('$1')+64*ord('$2')+ord('$3')-925824".$rep[1], $string);  
        $string = preg_replace("/([\\xf0-\\xf7])([\\x80-\\xbf])([\\x80-\\xbf])([\\x80-\\xbf])/e", $rep[0]."262144*ord('$1')+2048*ord('$2')+64*ord('$3')+ord('$4')-63185024)".$rep[1], $string);
      

      return $string;
      }

      Leider ist der Code schwer nachvollziehbar -- ich schaffe es selbst nicht...

      Caramba!
      Grüße aus Biberach Riss,
      Candid Dauth (ehemals Dogfish)

      --
      „Jemanden zu lieben bedeutet, ihn nicht zu erdrücken, auch wenn man es gerne wollte – aus Liebe.“ | Mein SelfCode
      http://cdauth.net.tc/
      1. Hallöle,

        Ungefähr so hatte ich das damals auch gemacht, jedoch ist es sehr rechenaufwändig, jedes Zeichen einzeln zu überprüfen. Bei großen Dateien dauerte die Berechnung auf unserem 133-MHz-Server teilweise zwei Minuten. Also beschloss ich, das Ganze etwas einfacher zu lösen, und löste die Hex-Werte auf, multiplizierte aus und kam irgendwann auf den folgenden Code aus regulären Ausdrücken, wobei die großen Seiten nur noch zwei Sekunden zu berechnen brauchten.

        Mag sein, daß das bei langen Strings einen Gewinn bringt.
        Bei mir mit vielen (max. ~25000) kurzen Strings (max. theoretisch 100, praktisch nicht länger als 40 Zeichen), von denen viele nur US-ASCII-Zeichen enthalten und einige wenige Strings nur wenige nicht-US-ASCII-Zeichen enthalten, nehmen sich die beiden Methoden nichts (Durchschnitt über je 20 Messungen: 12,71s <--> 12,65s - wobei der größte Teil der Zeit durch die Ausgabe der Daten verbraucht werden dürfte).

        cu,
        Robert