如何获取utf-8string中给定字符的代码点号?

我想获得给定的UTF-8string的UCS-2代码点。 例如,“你好”这个词应该变成“0068 0065 006C 006C 006F”。 请注意,angular色可能来自任何语言,包括东亚语言之类的复杂脚本。

所以,问题归结为“将给定的字符转换为其UCS-2代码点”

但是,如何? 因为我很匆忙,请各位帮忙,非常感谢。

提前致谢


提问者回复的转录张贴为答案

感谢您的回复,但它需要在PHP 4或5,但不是6。

该string将是来自表单字段的用户input。

我想实现一个PHP版本的utf8to16或者utf8decode就好

function get_ucs2_codepoint($char) { // calculation of ucs2 codepoint value and assign it to $hex_codepoint return $hex_codepoint; } 

你可以帮助我的PHP或可以完成与上述版本的PHP?

再次感谢你。

Scott Reynen写了一个将UTF-8转换为Unicode的函数。 我发现它看着PHP文档 。

 function utf8_to_unicode( $str ) { $unicode = array(); $values = array(); $lookingFor = 1; for ($i = 0; $i < strlen( $str ); $i++ ) { $thisValue = ord( $str[ $i ] ); if ( $thisValue < ord('A') ) { // exclude 0-9 if ($thisValue >= ord('0') && $thisValue <= ord('9')) { // number $unicode[] = chr($thisValue); } else { $unicode[] = '%'.dechex($thisValue); } } else { if ( $thisValue < 128) $unicode[] = $str[ $i ]; else { if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3; $values[] = $thisValue; if ( count( $values ) == $lookingFor ) { $number = ( $lookingFor == 3 ) ? ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ): ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 ); $number = dechex($number); $unicode[] = (strlen($number)==3)?"%u0".$number:"%u".$number; $values = array(); $lookingFor = 1; } // if } // if } } // for return implode("",$unicode); } // utf8_to_unicode 

使用一个现有的工具,如iconv ,或任何库与你正在使用的语言。

如果你坚持自己的解决scheme,请阅读UTF-8格式。 基本上,每个代码点存储为1-4个字节,取决于代码点的值。 范围如下:

  • U + 0000 – U + 007F:1字节:0xxxxxxx
  • U + 0080 – U + 07FF:2字节:110xxxxx 10xxxxxx
  • U + 0800 – U + FFFF:3个字节:1110xxxx 10xxxxxx 10xxxxxx
  • U + 10000 – U + 10FFFF:4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

其中每个x是数据位。 因此,通过查看第一个字节,可以知道每个代码点构成了多less个字节:如果以0开头,则是1个字节的字符。 如果它以110开头,则是一个2字节的字符。 如果从1110开始,它是一个3字节的字符。 如果它以11110开始,它是一个4字节的字符。 如果从10开始,它是多字节字符的非起始字节。 如果从11111开始,这是一个无效的字符。

一旦你找出字符中有多less字节,这只是一个问题,如果有点混乱。 另请注意,UCS-2不能代表U + FFFF以上的字符。

既然你没有指定一种语言,下面是一些示例C代码(省略了错误检查):

 wchar_t utf8_char_to_ucs2(const unsigned char *utf8) { if(!(utf8[0] & 0x80)) // 0xxxxxxx return (wchar_t)utf8[0]; else if((utf8[0] & 0xE0) == 0xC0) // 110xxxxx return (wchar_t)(((utf8[0] & 0x1F) << 6) | (utf8[1] & 0x3F)); else if((utf8[0] & 0xF0) == 0xE0) // 1110xxxx return (wchar_t)(((utf8[0] & 0x0F) << 12) | ((utf8[1] & 0x3F) << 6) | (utf8[2] & 0x3F)); else return ERROR; // uh-oh, UCS-2 can't handle code points this high } 

我很开心,因为我刚刚在期末考试中把这个问题交给了学生。 这是一个UTF-8草图:

 hex binary UTF-8 binary 0000-007F 00000000 0abcdefg => 0abcdefg 0080-07FF 00000abc defghijk => 110abcde 10fghijk 0800-FFFF abcdefgh ijklmnop => 1110abcd 10efghij 10klmnop 

这里是一些C99代码:

 static void check(char c) { if ((c & 0xc0) != 0xc0) RAISE(Bad_UTF8); } uint16_t Utf8_decode(char **p) { // return code point and advance *p char *s = *p; if ((s[0] & 0x80) == 0) { (*p)++; return s[0]; } else if ((s[0] & 0x40) == 0) { RAISE (Bad_UTF8); return ~0; // prevent compiler warning } else if ((s[0] & 0x20) == 0) { if ((s[0] & 0xf0) != 0xe0) RAISE (Bad_UTF8); check(s[1]); check(s[2]); (*p) += 3; return ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + ((s[2] & 0x3f)); } else { check(s[1]); (*p) += 2; return ((s[0] & 0x1f) << 6) + ((s[1] & 0x3f)); } } 

PHP代码(假定有效的utf-8,不检查无效的utf-8):

 function ord_utf8($c) { $b0 = ord($c[0]); if ( $b0 < 0x10 ) { return $b0; } $b1 = ord($c[1]); if ( $b0 < 0xE0 ) { return (($b0 & 0x1F) << 6) + ($b1 & 0x3F); } return (($b0 & 0x0F) << 12) + (($b1 & 0x3F) << 6) + (ord($c[2]) & 0x3F); }