Php 如何获取utf-8字符串中给定字符的代码点编号?
我想获得给定UTF-8字符串的UCS-2代码点。例如,单词“hello”应该变成类似“0068 0065 006C 006C 006F”的东西。请注意,字符可以来自任何语言,包括复杂的脚本,如东亚语言 因此,问题归结为“将给定字符转换为其UCS-2代码点” 但是怎么做呢?请,我很忙,任何帮助都将非常感谢Php 如何获取utf-8字符串中给定字符的代码点编号?,php,unicode,Php,Unicode,我想获得给定UTF-8字符串的UCS-2代码点。例如,单词“hello”应该变成类似“0068 0065 006C 006C 006F”的东西。请注意,字符可以来自任何语言,包括复杂的脚本,如东亚语言 因此,问题归结为“将给定字符转换为其UCS-2代码点” 但是怎么做呢?请,我很忙,任何帮助都将非常感谢 提问者回答的抄写,作为答案张贴 感谢您的回复,但它需要在PHPV4或5中完成,而不是在6中 该字符串将是来自表单字段的用户输入 我想实现一个PHP版本的utf8to16或utf8decode之
提问者回答的抄写,作为答案张贴 感谢您的回复,但它需要在PHPV4或5中完成,而不是在6中 该字符串将是来自表单字段的用户输入 我想实现一个PHP版本的utf8to16或utf8decode之类的
function get_ucs2_codepoint($char)
{
// calculation of ucs2 codepoint value and assign it to $hex_codepoint
return $hex_codepoint;
}
您能帮助我使用PHP吗?或者可以使用上面提到的PHP版本来完成吗?使用现有的实用程序,例如,或您使用的语言附带的任何库 如果你坚持推出自己的解决方案,请仔细阅读格式。基本上,根据代码点的值,每个代码点存储为1-4字节。范围如下:
- U+0000-U+007F:1字节:0xxxxxxx
- U+0080-U+07FF:2字节:110xxxxx 10xxxxxx
- U+0800-U+FFFF:3字节:1110xxxx 10xxxxx 10xxxxxx
- U+10000-U+10FFFF:4字节:11110xxx 10xxxxx 10xxxxx 10xxxxxx
wchar_t utf8_char_to_ucs2(const unsigned char*utf8)
{
如果(!(utf8[0]&0x80))//0xxxxxxx
返回(wchar_t)utf8[0];
如果((utf8[0]&0xE0)==0xC0)//110xxxxx
return(wchar_t)((utf8[0]&0x1F)我很开心,因为我刚刚在期末考试中给学生们出了这个问题。下面是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));
}
}
静态无效检查(字符c){
如果((c&0xc0)!=0xc0)上升(坏的UTF8);
}
uint16_t Utf8_解码(字符**p){//返回代码点和前进*p
char*s=*p;
如果((s[0]&0x80)==0){
(*p)++;
返回s[0];
}else如果((s[0]&0x40)==0){
升起(坏的_UTF8);
返回~0;//防止编译器警告
}else if((s[0]&0x20)==0){
如果((s[0]&0xf0)!=0xe0)上升(错误的UTF8);
支票[1];支票[2];
(*p)+=3;
return((s[0]&0x0f)向写入了一个函数。我发现它正在查看
函数utf8到unicode($str){
$unicode=array();
$values=array();
$lookingFor=1;
对于($i=0;$i=ord('0')&&$thisValuePHP代码(假定有效的utf-8,不检查无效的utf-8):
功能ord_utf8($c){
$b0=作战需求文件($c[0]);
如果($b0<0x10){
返回$b0;
}
$b1=作战需求文件($c[1]);
如果($b0<0xE0){
返回($b0&0x1F)在php>=7.2
中使用mb_ord()
或此功能:
function ord_utf8($c) {
$len = strlen($c);
$code = ord($c);
if($len > 1) {
$code &= 0x7F >> $len;
for($i = 1; $i < $len; $i++) {
$code <<= 6;
$code += ord($c[$i]) & 0x3F;
}
}
return $code;
}
哎哟,很抱歉在C代码上浪费您的时间。但我希望这个小图表对您有所帮助。check()函数是否已损坏?它是否应该测试:if((C&0xC0)!=0x80)?还有,RAISE宏是什么?感谢check()中的错误修复函数。为我在期末考试前一天晚上写代码服务。加薪是从。我写了那个函数。原始函数在这里,还有一些你可能会发现有用的函数:@Reynen,小世界,嗯?我编辑了我的帖子,给你信用和一些广告。请,哦,请叫它utf8\u to\u utf16
。两者都是“Unicode”表示为Unicode代码点。@ScottReynen 404 link,您还有原始的吗?很好,只是当字符已经是ASCII时它失败了。0x10应该是0x80,以捕获完整的ASCII范围。
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
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);
}
function ord_utf8($c) {
$len = strlen($c);
$code = ord($c);
if($len > 1) {
$code &= 0x7F >> $len;
for($i = 1; $i < $len; $i++) {
$code <<= 6;
$code += ord($c[$i]) & 0x3F;
}
}
return $code;
}
$string = 'abcde';
$string = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);