Python sort key methods for UTF-8 encoded Chinese character strings based on either Pinyin (pronunciation) or Bihua (strokes).
为UTF-8编码下的中文文字串提供类似英文字符串的排序功能:可分为以拼音排序和笔画数排序。一个包括4万多中文文字的数据文件为各种简体繁体的文本分析提供前所未有的支持。
Unicode下的中文字符的分布并没有太多规律,大致上是按照部首排下来,繁体和简体穿插而行。当需要排序的时候,比如人名排序,关键词排序等,如果简单的按照Unicode的顺序排序得到的结果并不是以中文使用者习惯的排序。
我们希望最后的使用非常简洁,可以如同排列英文字符串一样,只是告诉排序程序使用引进的key函数,为每一个中文文字串提供一个变体字符串,而这个字符串是按照拼音或者笔画数排列的。
为此,我们为每一个中文字编码,或者说提供一个index值,比如说按拼音排序,如果字a
的拼音比b
靠前,那么index(a) < index(b)
,如果a
和b
的拼音相同,音调也相同,但是a
的笔画数比b
少,那么依然index(a) < index(b)
。如果拼音完全相同,笔画数也完全相同,那么我们就比拼它们的Unicode代码,一般来说部首笔画少的会更靠前。总之,不会有两个汉字拥有完全一样的index。按照笔画数排序也类似,我们优先考虑笔画,然后考虑拼音,最后考虑Unicode。
编码设计为12位字符串。7位给拼音,大写字母靠左对齐,右部如有空位填0
;2位给总笔画数,个位数左边填0
;5位给16进位制Unicode码,靠右对齐,左边有空填0
。示例:“赵”字的拼音编码是ZHAO400
, 笔画编码是09
,Unicode编码是08d75
。那么“赵”字的拼音index是ZHAO4000908d75
,笔画index是09ZHAO40008d75
。
对于非中文文字的字符,我们只用Unicode编码,依然使用14位码,左边用0补齐。比如字符a
会被编码为00000000000097
。只要是非中文字符,始终会比中文字符排位顺序靠前,其顺序由Unicode编码决定。
我们的key函数会将包含N
个中文文字的字符串转变成N * 14
长的字符串,传递给python内置的比较函数。
参考demo.py。
排序最大的难点在于多音字。4万个汉字有4万9千个读音。比如"那“字有8个读音。汉字的多音字有些是历史遗留,现在已经不常用,我们可以选择一个常用音进行排序。但是对于目前还在常用的情况就不适用。比如说“重新”和“重要”里的“重”字都很常用,“长度”和“增长”里的“长”字也都很常用。我们无法区分这些发音,只能选择其中一个,通常来说是拼音靠前的“重新”和“长度”。对于这些多音字,我对1000多个汉字手工进行了修正,但是相信有的修正可能有错误,有的未能修正。