Unicode字符的兼容性问题--长得一样的汉字怎么会有多个编码?

昨天半夜帮同学排查问题,明明是一样的汉字,但是字符串比较结果却是False

 

 检查了半天,发现是utf-8的编码不同,对方的Mac电脑的Pycharm把这两个编码不同的汉字显示的完全一样

 

玉 玉

你的电脑上看得出来这两个字的区别么?

但是在我的电脑(Windows10+VisualStudioCode)上显示的就很明显

 

 

问题产生的原因

(转自https://www.qqxiuzi.cn/wz/zixun/1717.htm):

---------------------------------------------------------------------------------------------------------------------------------------

Unicode 之初收录汉字遵循两个基本原则:表意文字认同原则和字源分离原则。

所谓表意文字认同原则,即“只对字,不对形”编码,将同一字的不同字形(即异体字,不适用繁简体)合并。例如“房”字的第一笔,在中日韩的写法都不同,但它本身是同一个字,只给一个编码,而写法的不同交由字体进行区分。

字源分离原则,是指一个字源中同时收录了同一个字的不同字形,则给予两个字形分别编码。例如:“戶”、“户”、“戸”三个字。

基于这两个原则,Unicode 能大幅减少收录汉字的数量。然而这两个原则是相互对立的,字源分离原则破坏了认同原则中的“只对字,不对形”编码之原则,使某些汉字获得两个或多个编码,亦遭受不少批评。例如“値”和“值”。

所以,在 Unicode 1.0 收录了 20915 个汉字(20902个基本汉字 + 汉字〇 + 12个兼容表意汉字)之后,字源分离原则被放弃。此后,同一字源中不同写法的汉字,正统的编入正式编码区,而异体字则编入“兼容表意文字区”。

Unicode 12.1 兼容表意文字编码区域:
0号平面 F900-FAFF 中日韩兼容表意文字 (CJK Compatibility Ideographs)
2号平面 2F800-2FA1F 中日韩兼容表意文字增补 (CJK Compatibility Ideographs Supplement)

------------------------------------------------------------------------------------------------------------------------------------------

 

启示:

1,尽量不要使用Unicode字符集中的兼容表意文字编码区域,这一点在从OCR文档中复制文字时要尤其注意,在写代码时遇到字符串尽量Ctrl+C Ctrl+V

2,使用合适的代码字体,有助于你看出字符中的细微差别

3,尽量不要使用Unicode字符作为键值

 

    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")
    default_name = default_name.replace("", "")

 

posted @ 2022-05-19 11:30  Isakovsky  阅读(1775)  评论(0编辑  收藏  举报