Last active
March 2, 2022 01:46
-
-
Save mildcore/35c8fe5bfaefe7d100dba198b65c3669 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
r""" | |
本代码的例子:一个扩展平面字符,CJK统一表意文字扩展B第一个字符。(你的环境可能无法正确显示,实际字符可自行搜索代码点) | |
https://unicode-table.com/en/20000/ | |
𠀀 | |
U+20000 | |
1.Unicode编码标准 | |
出于区别,暂称之为编码标准。 | |
Unicode: 规定了代码点【Code Point】到字符的一一对应。世界统一。 | |
Unicode字符范围 U+0000 - U+10 FFFF, 有17个平面Plane, 以后会不会再增加,那是以后的事。 | |
Plane-0 为基本平面(Basic Multilingual Plane) : U+0000 - U+FFFF | |
注:编码标准常被称为‘XX码’ | |
注:Unicode被国际标准化组织收录为ISO/IEC 10646,Information technology -- Universal Coded Character Set (UCS), | |
Unicode是不断发展扩充的,两者可认为是不断进行同步以保持一致的。 | |
2.字符在计算机中的存储。 | |
叫法:字符编码、编码集、encoding、character_set等 | |
计算机对于Unicode代码点的实际存储,可以有自己的实现方式,实现了CodePoint到存储字节的转换【并不是直接 | |
把CodePoint的二进制存进去,而是经过再计算了】。 | |
出于节省空间等考虑,可以对CodePoint进行再编码,实现诸如变长字节等方式存储。 | |
utf-8, utf-16, utf-32等 | |
注:根据我目前的理解,字符编码(encoding、character_set)都会有自己认定的一个编码标准。 | |
3.除了Unicode标准外,可能有其他不同的编码标准。 | |
3.1 比如中国可以有自己的编码标准。以及GB2312、GBK等等先不提了,后面再研究。 | |
3.2 ASCII标准码,7bit,美国信息交换标准码,被Unicode兼容. | |
3.3 E-ASCII, 即ASCII扩展码,把一个字节剩余的 1bit 用上。典型的有ISO/IEC 8859系列一堆不同的编码标准 | |
ISO/IEC 8859-1 (Latin-1) - 西欧语言 # Latin-1被Unicode兼容 | |
ISO/IEC 8859-2 (Latin-2) - 中欧语言 | |
注:几个编码标准【ASCII】、【ISO/IEC 8859-1 (Latin-1)】、Unicode之间是互相向下兼容的。 | |
很多编码标准会选择兼容ASCII. | |
4.python中字符(串)表示方式。 | |
python字符没有单独类型,用字符长度为1的字符串来表示一个字符。 | |
<a>. 获取字符的Unicode值, ord(Char) | |
<b>. 根据Unicode值,构造字符 chr(CodePoint) | |
python字符串里字符表示法: | |
<1>.可以正确显示时,直接写原字符。跟OS、终端等等有关,有些环境可能无法显示,粘贴过去变成两个字符。 | |
'𠀀' | |
len(..) = 1 | |
<2>.\U表示法,必须是8位16进制,即4个字节。【扩展平面字符必须要用\U表示】 | |
'\U00020000' | |
len(..) = 1 | |
<3>.\u表示法,只能是4位16进制,即2个字节。【所以\u应该是只能表示Unicode基本平面的字符】 | |
'\u00020000'' | |
len(..) = 5, 实际上字符串是 '\u0002' + '0000' | |
<4>.\x表示法,只能是2位16进制,即1个字节。【这样只能表示ASCII码了,或者EASCII】 | |
'\x00020000' | |
len(..) = 7 | |
注:python字符串里每个\x看作一个字符, 还看到pycharm里空字符\x00是不会打印成空格的,idle会打印成空格 | |
<5>.\nnn表示法,只能是1-3位8进制数,即9bit,共512个字符(1个字节字符数的2倍, 不是2个字节哦)。 | |
'\7' '\027' '\107' | |
len(..) = 1 | |
for i in range(0, 0o777+2): | |
s = '\\%o' % i | |
a = 0 | |
exec('a=\'%s\'' % s) | |
if len(a) != 1: | |
print(i, a) | |
else: | |
print(a, sep='', end=(i+1) % 16 == 0 and '\n' or '') | |
注:与\u字符对比,两者在范围内字符是一致的 | |
for i in range(0, 0o777+2): | |
s = '\\u%04x' % i | |
a = 0 | |
exec('a=\'%s\'' % s) | |
if len(a) != 1: | |
print(i, a) | |
else: | |
print(a, sep='', end=(i+1) % 16 == 0 and '\n' or '') | |
5.关于字形,说两句 | |
拿Unicode这个编码标准来讲 | |
一个字符,可以有多种字形,简繁体等,但是其在Unicode里都是同一个字符,同一个Code Point. | |
本地计算机上显示的不同,是本地字库的问题,计算机根据码点去查库,查到那个字的具体字形,然后显示出来。 | |
更多内容可参考一下下面链接以及自行google: | |
https://zhuanlan.zhihu.com/p/51202412 # 讲了关于字体的问题、BOM等 | |
""" | |
def mypr(*args, sep='__', end='__\n', file=None): | |
return print('', *args, sep=sep, end=end, file=file) | |
if __name__ == '__main__': | |
a = '𠀀' # U+20000, '\U00020000' | |
b = '\U00020000' | |
c = '\u00020000' | |
d = '\x00020000' | |
mypr(a, 'CHAR(%s)' % len(a), a.encode()) | |
mypr(b, 'CHAR(%s)' % len(b), b.encode()) | |
mypr(c, 'CHAR(%s)' % len(c), c.encode()) | |
mypr(d, 'CHAR(%s)' % len(d), d.encode()) | |
# python字符串里每个\x看作一个字符, 还看到pycharm里空字符\x00是不会打印成空格的,idle会打印成空格 | |
_s = '\x00\x02\x00\x00' | |
mypr(_s, 'CHAR(%s)' % len(_s), _s.encode()) | |
print(chr(0x20000)) | |
print(ord('𠀀'), hex(ord('𠀀'))) | |
s = '' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment