Strings, Bytes, and Unicode in Python 2 and 3

Python 2 vs Python 3 String Handling

"Hello World"
Python 2a "str" object stored as bytes. Prefix it with "u" to get a "unicode" object which is stored as Unicode
Python 3a "str" object that stores Unicode. Prefix it with "b" to get a bytes object or use .encode.

Using the Unicode Sandwich model to handle Unicode

Unicode Sandwich model.png
当你的程序接收到 byte strings 后尽快将其解码为 Unicode,在你的程序中所有的对这些 strings 的操作都将会在 unicode 的形式下进行,最后将其编码回 byte strings 并输出。

Pragmatic Unicode - Unipain

Str vs Unicode
stra sequence of bytes
unicodea sequence of code points (unicode)

unicode .encode() -> bytes
bytes .decode() -> unicode

转换时的错误处理策略

strict(default)/replace/xmlcharrefreplace/ignore

my_unicode = u'Hi \u2119\u01b4\u2602\u210c\xf8\u1f24'
my_unicode.encode('ascii', 'replace')
>>> 'Hi ??????'

my_unicode.encode('ascii', 'xmlcharrefreplace')
>>> 'Hi ℙƴ☂ℌøἤ'

my_unicode.encode('ascii', 'ignore')
>>> 'Hi '

快速剔除字符串中的非ascii字符串: string.encode('utf-8').decode('ascii', 'ignore')

UTF-8编码字节含义

  • 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B独立的表示一个字符(ASCII码);
  • 如果B的第一位为1,第二位为0,则B为一个多字节字符中的一个字节(非ASCII字符);
  • 如果B的前两位为1,第三位为0,则B为两个字节表示的字符中的第一个字节;
  • 如果B的前三位为1,第四位为0,则B为三个字节表示的字符中的第一个字节;
  • 如果B的前四位为1,第五位为0,则B为四个字节表示的字符中的第一个字节;

因此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节;根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为1),可判断编码是否有错误或数据传输过程中是否有错误。

GBK编码的中文可以依据读音进行正则检索,因为GBK编码是按读音排序的。(部分多音字)
UTF-8编码的中文可以依据部首进行正则检索,UTF-8不是按读音排序的,是按照部首排序的。

参考内容:
Strings, Bytes, and Unicode in Python 2 and 3
Pragmatic Unicode - Unipain
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
Python 3 Unicode and Byte Strings
UTF-8 - Wikipedia

标签: Unicode

添加新评论