Skip to content

Instantly share code, notes, and snippets.

@mildcore
Last active March 2, 2022 01:46
Show Gist options
  • Save mildcore/35c8fe5bfaefe7d100dba198b65c3669 to your computer and use it in GitHub Desktop.
Save mildcore/35c8fe5bfaefe7d100dba198b65c3669 to your computer and use it in GitHub Desktop.
#!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