UTF8 非 ASC 实例列表不起作用


List of UTF8 non-ASC occurrences not working

PHP 库缺少mb_ord()函数...也就是说,执行 ord(( 函数所做的事情,但对于 UTF8(或"mb"多字节,所以"mb_ord"(。我从这里用了一些线索,

 $ord = hexdec( bin2hex($utf8char) ); //decimal 

我想mb_substr($text, $i, 1, 'UTF-8')得到"1 utf8-char"......但是$ord不会返回我们期望的值。

上下文

此代码不起作用:不显示像 177 (plusmn( 这样的代码。

 $msg = '';
 $text = "... a UTF-8 long text... Ą ⨌ 2.5±0.1; 0.5±0.2 ...";
 $allOrds = array(); 
 for($i=0; $i<mb_strlen($text, 'UTF-8'); $i++) {
    $utf8char = mb_substr($text, $i, 1,  'UTF-8'); // 1=1 unicode character?
    $ord = hexdec( bin2hex($utf8char) ); //decimal 
    if ($ord>126) { //non-ASCII
      if (isset($allOrds[$ord])) $allOrds[$ord]++; else $allOrds[$ord]=1;
    }
 }
 foreach($allOrds as $o=>$n)
    $msg.="'n entity #$o occurs $n times";
 echo $msg;

输出

entity #50308 occurs 1 times
entity #14854284 occurs 1 times
entity #49841 occurs 2 times

所以(见实体表(,49841不是177,14854284(iiiint(不是10764。

执行 ord(( 函数所做的事情,但对于 UTF8

为此,您首先需要定义它到底是什么。 ord为您提供一个字节的数值。这经常被混淆为"字符的价值",但由于编码是一个没有意义的复杂主题。因此,ord == 字节的数值。那么,您期望"MB版本的ord"究竟会做什么?

无论如何,你得到的是两个(或更多(字节的数值。比如说,UTF-8 中的字符"漢"被编码为三个字节E6 BC A2。这就是bin2hex给你的。 然后hexdec将其转换为十进制,这是一个相当大的数字。这个数字与Unicode代码点6F22完全无关,你真正追求的是Unicode代码点6F22。这是因为 UTF-8 编码需要更多的额外字节来编码此代码点,因此 U+6F22 (漢( 不会转换为字节6F 22

您已经链接到另一个问题,该问题可以满足您的需求:

list(, $ord) = unpack('N', mb_convert_encoding($utf8Character, 'UCS-4BE', 'UTF-8'));

这基本上使用相同的逻辑,但基于UCS-4编码,其中代码点恰好与字节非常吻合。