1. 程式人生 > 其它 >Unicode字元的相容性問題--長得一樣的漢字怎麼會有多個編碼?

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字符集中的兼容表意文字編碼區域,這一點在從PDF文件中複製文字時要尤其注意,在寫程式碼時遇到字串儘量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("", "")