Entsprechungen gesucht
Tom
- php
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
Wie kann man den Codepoint eines Multibyte-Zeichens ermitteln?
Gibt Dein(e) Zeichen hier ein, dann kriegst Du Codepoint(s) (und ein bischen mehr).
Horst
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
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
)
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!
Lieber hotti,
return($this->CODEPOINTS);
wozu die Klammern? Willst Du da wirklich einen boolschen Wert zurückliefern?
Liebe Grüße,
Felix Riesterer.
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
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