數日前在 Ptt Perl 版兩篇回應關於 Unihan 查詢的一些文字 (1, 2),原始 的問題,是在詢問如何查詢 Unicode 之中的漢字。以下將回應文章重新訂正編輯之後,重新 發表如下。

Unicode 方面的檢索,可直接使用 unicode.org,其中有一頁是漢字相關的:

http://www.unicode.org/charts/unihan.html

雖然 CTA 做得好像不存在似的,但 Lookup 鈕旁邊可以輸入漢字,並查到各種資料。以下是「行」字 ( U+884C )

http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E8%A1%8C

在這頁最下面可以看到這碼位有個對應的 kZVariant 是 U+FA08。

關於 z variant 其奇妙無比的解釋,請詳閱

http://www.unicode.org/reports/tr38/index.html#N10211 http://www.unicode.org/reports/tr38/index.html#kZVariant

摘錄如下:

... Briefly, however, the three-dimensional model uses the x-axis to represent meaning,
and the y-axis to represent abstract shape. The z-axis is used for stylistic variations.

簡譯如下:

... 不過簡單地說, 就是以三維模型來表示變種。X 軸表意,Y 軸象型。Z 軸則用來區別風格。

也就是說,如果有兩個碼位互為 Z 變種,表示那兩碼位對應的字是同意同型,但「書寫風格」不同。

不過由許多例子看來,同型倒也不是指筆劃完全相同,實在是很奇妙。像「說」與「説」這對是 Z 變種, 「貓」與「猫」則是 Y 變種。

要得知哪些碼位有 Z 變種,可下載 Unihan.zip (在頁面左方可找到連結)

<ftp://ftp.unicode.org/Public/UNIDATA/Unihan.zip>

解開在找 Unihan_Variants.txt 檔案中找 kZVariant

> grep kZVariant Unihan_Variants.txt | perl -CO -aE 'say join " ", map { ($_, chr(hex($_ =~ s/^U\+//r)))} @F[0,2]' | head -20
U+3588 㖈 U+439B 䎛
U+363D 㘽 U+39B3 㦳
U+39B3 㦳 U+363D 㘽
U+3ADA 㫚 U+66F6 曶
U+418B 䆋 U+9F9D 龝
U+439B 䎛 U+3588 㖈
U+4E04 丄 U+4E0A 上
U+4E05 丅 U+4E0B 下
U+4E0A 上 U+4E04 丄
U+4E0B 下 U+4E05 丅
U+4E0C 丌 U+5176 其
U+4E0D 不 U+F967 不
U+4E16 世 U+4E17 丗
U+4E17 丗 U+4E16 世
U+4E18 丘 U+4E20 丠
U+4E21 両 U+5169 兩
U+4E23 丣 U+9149 酉
U+4E26 並 U+5E77 幷
U+4E2C 丬 U+723F 爿

(ptt 可能無法儲存某些字,會變問號,請自已試試)

Dan Kogai 曾經釋出 Unicode::Unihan ,基本上是處理這個檔案,但已經七年沒更新了,自行處理一下可能較為適合。

此外,討論 「㊎」(U+328E)與「金」(U+91D1) 兩字,「㊎」為圈起來的「金」,是否應視為等同於「金」?

私以為,㊎、金二字在在各種使用情境中多半指稱不同實物,因此意義不同,不必視為同一個字處理。 而 Unicode 中有組合用字,也就是由多個碼位來合成一個字符。遇到時,「〇」和「金」會各自出現。

而組字專用的碼位,其名稱都會有 "COMBINING" 這個字,實際上會使用到是兩個以上的碼位來表示一個組合字, 所以其實很好處理。可以使用 uni 來找到所有 COMBINING 碼位:

使用方法如下:

> uni combining | head
 ̀ - U+00300 - COMBINING GRAVE ACCENT
 ́ - U+00301 - COMBINING ACUTE ACCENT
 ̂ - U+00302 - COMBINING CIRCUMFLEX ACCENT
 ̃ - U+00303 - COMBINING TILDE
 ̄ - U+00304 - COMBINING MACRON
 ̅ - U+00305 - COMBINING OVERLINE
 ? - U+00303 - COMBINING TILDE
....

也可以直接打字:

> uni 金
金- U+091D1 - CJK UNIFIED IDEOGRAPH-91D1

以「圈起來的金」為例,則是 U+20DD 後面接上 U+91D1。

配合 charnames::viacode, ord 等函式,也可自行在程式中取得該碼位在 Unicode 標準中的「名字」:

> perl -Mcharnames=:full -E 'say charnames::viacode("91D1")'
CJK UNIFIED IDEOGRAPH-91D1

> perl -Mutf8 -Mcharnames=:full -E 'say charnames::viacode(ord("金"))'
CJK UNIFIED IDEOGRAPH-91D1

也就是說工具都有了,要把組合專用的碼位除掉,其實頂容易的。

但是否要去掉組合用的碼位,則視用途了... 繁簡轉換及 z variant 比較像是正規化處理。 但通常是在搜尋這個 領域的應用才比較需要。