字符问题
Unicode 标准把字符的标识和具体的字节表述进行了明确区分
- 字符的标识,即码位,是0-1114111的数字(十进制)
- 编码是在码位与字节序列之间转换时使用的算法。
把码位转换为字节序列是编码,把字节序列转为码位是解码
字节概要
python内置了两种基本的二进制序列类型:
- bytes:python3引入的不可变类型
- bytearray: 可变类型
bytes或bytearray对象的各个元素是介于0-255(含)之间的整数。二进制序列的切片始终是同一类型的二进制序列,包括长度为1的切片。
虽然二进制序列其实是整数序列,但是它们的字面量表示法表明其中有ASCII文本。因此,各个字节的值可能会使用下列三种不同的方式显示。 - 可打印的ASCII范围内的字符(从空格到~)。使用ASCII字符本身。
- 制表符,换行符,回车符和* 对应的字节,使用转义序列\t,\n,\r* 和\.
- 其他字节的值,使用十六进制转义序列(例如, \x00是空字节)
构建bytes或bytearray实例还可以调用各自的构造方法,传入下述参数。 - 一个str对象和一个encoding关键字参数
- 一个可迭代对象,提供0~255之间的数值。
- 一个整数,使用空字节创建对应长度的二进制序列。python3.6会将其删除
- 一个实现了缓冲协议的对象(如bytes,bytearray,memoryview,array.array);此时,把源对象中的字节序列复制到新建的二进制序列中.
注意 - 使用缓冲类对象创建bytes或者bytearray对象时,始终复制源对象中的字节序列。与之相反,memoryview对象允许在二进制数据结构之间共享内存。
结构体和内存视图
struct模块提供了一些函数,能处理bytes,bytearray和memoryview对象。
基本的编解码器
utf-8之类的
了解编码问题
- UnicodeEncodeError: 把字符串转成二进制序列时
- UnicodeDecodeError: 把二进制序列转换为字符串时
- SyntaxError: 源码的编码与预期不符。
处理文本文件
处理文件的最佳实践是‘Unicode三明治’。
- 尽早把输入(例如读取文件)的字节序列解码成字符串。
- 在其他处理过程中,一定不能编码或解码
- 对输出来说,则要尽量晚的把字符串编码成字节序列。
为了正确比较而规范化Unicode字符串。
因为Unicode有组合字符。一个单词可能有两种方式构成,分别会有4个或者5码位。但是结果是完全一样的,在python中,因为看到的是不同的码位序列,因此判定二者不相等。
解决这个问题可以使用unicodedata.normalize函数提供的Unicode规范化。
- NFC :使用最少的码位构成等价的字符串
- NFD :把组合字符分解成基字符和单独的组合字符。
- NFKC : 兼容模式
- NFKD :兼容模式
上面的两种兼容模式规范化形式只能在特殊情况下使用,例如搜索和索引。不能用于持久存储。
大小折叠
大小写折叠其实就是把所有文本转为小写,再做些其他转换。这个功能由str.casefold()方法支持。
去掉变音符合
思路:
- 使用NFD规范化unicode字符。分解为基字符和组合记号
- 过滤所有组合记号
- 重组所有字符
Unicode文本排序
可以使用PyUCA库。
Unicode 数据库
Unicode标准提供了一个完整的数据库,不仅包括码位与字符名称之间的映射,还有各个字符的元数据,以及字符之间的关系。
- unicodedate.name()
- unicodedata.numeric()
- .isdecimal():
- .isnumeic():
支持字符串和字节序列的双模式API
re和os模块