2.1.2. 在处理中文简体和中文繁体的的时候,使用目标编码中不存在的中文字符,也会导致UnicodeEncodeError

在一个UTF-8的Python文件中,有如下代码:

str = '电脑';
......
goods.append(urllib.quote(str.decode('utf-8').encode('big5')));
        

此时,就会出现错误:

UnicodeEncodeError: 'big5' codec can't encode character u'\u7535' in position 0: illegal multibyte sequence

此问题的原因在于,对于所输入的str类型的中文简体字符”电脑“来说,虽然通过str.decode('utf-8')可以获得了Unicode的中文简体字符”电脑“

但是将此Unicode类型的,简体中文字符”电脑“,去进行BIG5编码的时候,结果由于BIG5编码中,根本就不存在上述这两个简体中文的汉字”电脑“,由此出现上述UnicodeEncodeError的错误。

即,无法将简体中文的”电脑“,从Unicode转换为BIG5编码,因为BIG5编码字符集中,就不存在”电脑“这两个字符。

对此问题,详细去探究,就可以更了解中文简体和中文繁体之间的差别。

此处,先来明确一下我们的目标,即,希望是在BIG5编码中,能显示”电脑“这两个字符。

而对于BIG5编码所对应的所有字符,可以去Big5 (Traditional Chinese) character code table中查找

我们会发现,BIG5编码中,根据就找不到这两个字符。

那如何才能让”电脑“这两个字符,在繁体中显示呢?

那就需要,将中文简体的”电脑“,去先转换为对应的中文繁体字,然后就可以编码为BIG5,可以显示了。

而关于中文简体和中文繁体之间的转换,可以去这里:

简繁转换

进入该网站后,输入”电脑“,然后点击”TW Unicode“或”TW BIG“,就可以转换为对应的繁体字”電腦“了。

很明显,”電腦“这两个中文繁体字,那肯定是能在Big5 (Traditional Chinese) character code table中找到的

而对应的,这几个中文字符所对应的Unicode的值,可以去Unicode Lookup查到。

此处整理如下:

表 2.1. ”电脑“和”電腦“所对应的Unicode值

Unicode characterOctDecHexHTML
电 cjk unified ideograph 7535072465300050x7535电
脑 cjk unified ideograph 81110100421330410x8111脑
電 cjk unified ideograph 96fb0113373386510x96FB電
腦 cjk unified ideograph 81660100546331260x8166腦


此处,“电”所对应的Unicode值为7535,Unicode写法为\u7535,就是对应着上述出错的内容中所指示的,

BIG5编码器,无法对于Unicode为\u7535的字符进行编码,即BIG5无法编码“电”,因为其本身就没这个字符。

对应的,如果用GB2312/GBK/GB18030去编码“电”,那么肯定是可以的,但是肯定也是无法编码“電”的。

所以,对于中文简体和繁体之间,如果想要正确显示,需要先转换为对应繁体或简体,然后才能用正确的编码,去解析其所支持的字符的。

而有人看到这里,可能会疑惑了,因为比如对于有些中文字符,比如“手机”,

虽然没有去用什么简体转换为繁体,而直接用上述BIG5去编码,会发现程序可以正常执行,不会出现那个UnicodeEncodeError的

对此,你去简繁转换中搜一下“手”和“机”这两个汉字,发现BIG5编码中,也的确是存在这两个汉字的,

所以原因就很清楚了:对于有些字符,中文简体和中文繁体的写法,是一样的,所以才可以在GB212/GBK/GB18030和BIG5之间来回转换,而不会出现问题。

换句话说,如果你想要在BIG5编码中显示(编码)某个中文简体的话,那前提要确保该字符是可以在简繁转换中能查找到的。

否则,说明BIG5中没有改汉字,需要用到简繁转换去先进行简繁体转换,得到转换后的繁体字后,才能得到BIG5编码的字符,用BIG5去编解码,去显示对应的繁体中文。

上述步骤,很明显,可以省略了去BIG5编码表中查找,而直接利用上述简繁体转换的网站去实现转换,或者本地建立一个转换表,直接从输入的中文简体,得到输出的中文繁体,即可继续后续处理,而无需关注,在简体和繁体中,哪些是一样的写法,哪些是不一样的写法。