Tom: Entsprechungen gesucht

Hello,

für ASCII gibt es die guten alten Funktionen

ord()    http://de1.php.net/manual/en/function.ord.php
chr()    http://de1.php.net/manual/en/function.chr.php

Um ein einzelnes Zeichen aus einem String herauszuschneiden, gibt es
substr() http://de1.php.net/manual/en/function.substr.php
und bei Multibyte-Strings
mb_substr() http://de1.php.net/manual/en/function.mb-substr.php

...

Welche Funktionen stehen denn nun für Multibyte-Strings als Entsprechung für ord() und chr() zur Verfügung?

Im Prinzip habe ja auch schon diejenigen für ISO-8859-1 & Co. gefehlt.

Wie kann man den Codepoint eines Multibyte-Zeichens ermitteln?

Liebe Grüße aus dem schönen Oberharz

Tom vom Berg

--
 ☻_
/▌
/ \ Nur selber lernen macht schlau
http://bikers-lodge.com
  1. Wie kann man den Codepoint eines Multibyte-Zeichens ermitteln?

    Gibt Dein(e) Zeichen hier ein, dann kriegst Du Codepoint(s) (und ein bischen mehr).

    JavaScript

    Horst

  2. hi,

    Wie kann man den Codepoint eines Multibyte-Zeichens ermitteln?

    Offensichtlich gehts in PHP nicht so einfach wie in Perl. Ich würde dann so vorgehen:

    unpack("C*", "äöü");

    liefert Dir ein Array mit den Oktettenwertigkeiten. Dann guckst Du in stringview.js (das ist eine Opensource) nach der Funktion StringView.loadUTF8CharCode = function (aChars, nIdx), wenn Du den Algorithmus verstanden hast, setze diese JS-Funktion nach PHP um. Ich habe das mit dem €-Zeichen (3 Oktetten) mal in Perl probiert, das Ergebnis hat gestimmt ;)

    Horst

    1. Zum Basteln ;)
      Funktional, 3, 2, 1 Byte, den Rest kannste selber bauen, Codevorlage s.u.

        
      <?php  
        
      class Codepoint{  
          private function examine($part){  
              static $idx = 1;  
              if( ($part > 223) && ($part < 240)){ // 3 bytes  
                  $this->CODEPOINTS[] = ($part - 224 << 12) + ($this->OCTS[$idx + 1] - 128 << 6) + $this->OCTS[$idx + 2] - 128;  
                  $idx += 3;  
              }  
              elseif($part > 191 && $part < 224){  // 2 bytes  
                  $this->CODEPOINTS[] = ($part - 192 << 6) + $this->OCTS[$idx + 1] - 128;  
                  $idx += 2;  
              }  
              else{  
                  $this->CODEPOINTS[] = $part;  
                  $idx += 1;  
              }  
              return $idx;  
          }  
        
          public function cps($str){  
              $this->OCTS = unpack('C*', $str);  
        
              $this->CODEPONTS = array();  
              for($i = 1; $i <= sizeof($this->OCTS);){  
                 $i = $this->examine($this->OCTS[$i]);  
              }  
        
              return($this->CODEPOINTS);  
          }  
      }  
        
      $c = new Codepoint();  
      print_r($c->cps('€äöüA'));  
        
        
        
      #StringView.loadUTF8CharCode = function (aChars, nIdx) {  
      #  
      #  var nLen = aChars.length, nPart = aChars[nIdx];  
      #  
      #  return nPart > 251 && nPart < 254 && nIdx + 5 < nLen ?  
      #      /* (nPart - 252 << 32) is not possible in ECMAScript! So...: */  
      #      /* six bytes */ (nPart - 252) * 1073741824 + (aChars[nIdx + 1] - 128 << 24) + (aChars[nIdx + 2] - 128 << 18) + (aChars[nIdx + 3] - 128 << 12) + (aChars[nIdx + 4] - 128 << 6) + aChars[nIdx + 5] - 128  
      #    : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ?  
      #      /* five bytes */ (nPart - 248 << 24) + (aChars[nIdx + 1] - 128 << 18) + (aChars[nIdx + 2] - 128 << 12) + (aChars[nIdx + 3] - 128 << 6) + aChars[nIdx + 4] - 128  
      #    : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ?  
      #      /* four bytes */(nPart - 240 << 18) + (aChars[nIdx + 1] - 128 << 12) + (aChars[nIdx + 2] - 128 << 6) + aChars[nIdx + 3] - 128  
      #    : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ?  
      #      /* three bytes */ (nPart - 224 << 12) + (aChars[nIdx + 1] - 128 << 6) + aChars[nIdx + 2] - 128  
      #    : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ?  
      #      /* two bytes */ (nPart - 192 << 6) + aChars[nIdx + 1] - 128  
      #    :  
      #      /* one byte */ nPart;  
      #  
      #}  
        
      ?>  
      
      

      Codepoints sind dezimal, für hex siehe sprintf %X
      Array
      (
          [0] => 8364
          [1] => 228
          [2] => 246
          [3] => 252
          [4] => 65
      )

      1. Hier nun mein Klassenentwurf, zwei Methoden:

        codepoints('äöü€ß');

        Im return ein Array mit den Codepoints.

        binary(array(0x20AC, 228));

        Im return die Binary (Bytes für UTF-8 kodierte Zeichen)

        Viel Spaß damit!

      2. Lieber hotti,

        return($this->CODEPOINTS);

        wozu die Klammern? Willst Du da wirklich einen boolschen Wert zurückliefern?

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
        1. Hallo Felix,

          return($this->CODEPOINTS);
          wozu die Klammern?

          vielleicht einfach "der Ordnung halber"? - Weil das Argument bei sämtlichen Keywords für Kontrollstrukturen (if, while, for, ...) in Klammern steht?

          Willst Du da wirklich einen boolschen Wert zurückliefern?

          Was hat das damit zu tun? Tatsächlich bewirken die Klammern hier absolut *nichts*, außer dass das return-Statement damit etwas gefälliger aussieht.

          Ciao,
           Martin

          --
          Nicht jeder, der aus dem Rahmen fällt, war vorher im Bilde.
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        2. hi,

          return($this->CODEPOINTS);

          wozu die Klammern? Willst Du da wirklich einen boolschen Wert zurückliefern?

          ich frag mich, wozu ich diese Klasse überhaupt entworfen habe. Für Tom wahrscheinlich eher nicht, der schweigt sich hierzu beharrlich aus.

          Btw., in Perl sind das zwei Zeilen:

            
          use utf8;  
          print "@{[unpack 'U*', '€äöüß…']}"; # 8364 228 246 252 223 8230  
          
          

          Vielleicht findet die U-Schablone irgendwann auch mal zu PHP… ;)

          Horst

          --
          GGA