Jos*_*e G 4 python unicode python-2.7
在python中这三个命令打印相同的表情符号:
print "\xF0\x9F\x8C\x80"
print u"\U0001F300"
print u"\ud83c\udf00"
Run Code Online (Sandbox Code Playgroud)
如何在\ x,\ u和\ U转义之间进行转换?我无法想象这些十六进制数是如何相等的?
第一个是字节字符串:
>>> "\xF0\x9F\x8C\x80".decode('utf8')
u'\U0001f300'
Run Code Online (Sandbox Code Playgroud)
在u"\ud83c\udf00"
一个是UTF-16版本(四位Unicode转义)
在u"\U0001F300"
一个是码点的实际索引.
但数字如何相关? 这是一个棘手的问题.它由编码定义,没有明显的关系.为了给你一个想法,这里是一个"手动"编码索引0x1F300的代码点为UTF-8的例子:
旋风字符的索引为0x1f300,其范围为0x00010000 - 0x001FFFFF.此范围的模板是:
11110... 10...... 10...... 10......
Run Code Online (Sandbox Code Playgroud)
在哪里用代码点的二进制表示填充点.我无法告诉你为什么模板看起来像那样,它只是utf-8的定义.
这是我们的代码点的二进制表示:
>>> u''
u'\U0001f300'
>>> unichr(0x1f300)
u'\U0001f300'
>>> bin(0x1f300)
'0b11111001100000000'
Run Code Online (Sandbox Code Playgroud)
因此,如果我们采用字符串模板并将其填充(带有一些前导零,因为模板中有更多的插槽而不是我们编号中的有效数字),我们得到:
11110... 10...... 10...... 10......
11110000 10011111 10001100 10000000
Run Code Online (Sandbox Code Playgroud)
现在让我们将其转换回十六进制
>>> 0b11110000100111111000110010000000
4036988032
>>> hex(4036988032)
'0xf09f8c80'
Run Code Online (Sandbox Code Playgroud)
在那里你有代码点的UTF8表示.
对于UTF16 ,您的代码点有一个类似的魔术配方:从索引中减去0x10000,然后我们用零填充以获得20位二进制表示.前十位被添加到0xD800以给出第一个16位代码单元.最后十位被添加到0xDC00以给出第二个16位代码单元.
>>> bin(0x1f300 - 0x10000)[2:].rjust(20, '0')
'00001111001100000000'
>>> _[:10], _[10:]
('0000111100', '1100000000')
>>> hex(0b0000111100 + 0xd800)
'0xd83c'
>>> hex(0b1100000000 + 0xdc00)
'0xdf00'
Run Code Online (Sandbox Code Playgroud)
还有你的UTF 16版本,即带有小写版本的版本\u
.
您可能已经理解,这些表示中的十六进制数字之间可能没有明显的数字关系,它们只是同一代码点的不同编码.
归档时间: |
|
查看次数: |
1364 次 |
最近记录: |