0

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。

4

1 回答 1

1

做 ord() 函数做的事情,但对于 UTF8

为此,您首先需要定义它到底是什么。ord给你一个字节的数值。这通常被混淆为“字符的值”,但由于编码是一个没有意义的复杂主题。所以,ord== 一个字节的数值。那么,您希望“MB 版本ord”究竟能做什么?

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

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

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

这基本上使用了相同的逻辑,但它基于 UCS-4 编码,其中代码点恰好与字节对应得很好。

于 2013-10-09T12:15:50.807 回答