摘要:以 hunspell_ja_JP 項目文件為例淺析 goldendict 構詞法規則。(好吧,這篇文章比較硬,我也不知道該怎麼寫摘要了 2333
前言#
本文以MrCorn0-0/hunspell_ja_JP: Hunspell morphology dictionary for Japanese used in GoldenDict. (github.com)項目(以下簡稱 “原項目”)的構詞法文件為例,參考Linux hunspell 官網提供的 man 4 hunspell PDF 文件(以下簡稱 “手冊”)講解基礎的構詞法規則。
提前聲明:本人才疏學淺,只是大致弄清楚了原項目的構詞法文件的部分規則,可能會有錯誤的地方,希望大家理性閱讀,友好交流。另外原項目只針對日語,如果是其他語言的構詞法問題,我可能無法解答,請自行查閱手冊。
GoldenDict 的構詞法功能使用的技術主要是 Hunspell,這個本來是 Linux 端的拼寫檢查工具,所以 GoldenDict 和向德語系學生介紹 hunspell提到的略有區別,GoldenDict 的構詞法只有下面將會講解的後綴名為.dic
和 .aff
的 2 個文件,並沒有後綴名為.morph
、.good
、.wrong
、.sug
的文件,不過.dic
和.aff
文件的規則 Hunspell 的手冊是完全一致的。
關於這 2 個文件的作用,引用向德語系學生介紹 hunspell的說法:
- .dic 詞典文件,裡面的內容類似紙質詞典裡的詞頭 (lexem)。
- .aff 還原規則集,裡面寫了怎樣把一個加了前綴後綴或與其他詞語複合的複雜形式,轉化為一個詞典中存在的詞頭的許多組規則。
dic 文件基本格式#
dic 文件比較簡單,就是形如下面的文件(最開始的數字表示 dic 文件收錄的詞彙數量)
450851
あ
亜
亞
吾
我
高い/XA
部分單詞有個/
,後面還有看起來像是亂碼的東西,這種寫法可以直接理解為在告訴軟件單詞的詞性,表示這個單詞有一個名為XA
的變形規則,後面會詳細介紹,這裡只需要知道 dic 文件裡面可以指定一個單詞的詞性即可。
另外,GoldenDict 的 dic 文件收錄的單詞會在啟用構詞法功能時影響最終查詞結果,最好謹慎對待這份文件裡的單詞,不要貿然修改。
aff 文件#
aff 文件的規則非常複雜,下面只講解原項目使用到的規則,研究其他語言或者有其他需求的同學請自行查閱 Linux 項目的 man 4 Hunspell 手冊。(重要的事再重複一遍,本人英語也只有四級水平,讀手冊非常吃力,完全是靠猜測加驗證得出的結論,並不是讀手冊讀懂的。各位與其指望一個日語專業的英語學渣,不如自己嘗試一下呢:)
MAP#
先用一個例子介紹最好理解的 MAP 規則:
#拼寫變體
MAP 89
MAP あア
MAP かカ
MAP さサ
MAP たタ
MAP 89
表示下面將會有 89 條 MAP 規則。
MAP 規則簡單理解就是忽略指定字符的差異,比如MAP あア
表示輸入ア
會被當做あ
來處理,所以這個規則在原項目中是用來處理日語擬聲擬態詞的書寫習慣,比如チョコチョコ
在大多數權威詞典裡面都沒有,而經過規則替換後的ちょこちょこ
很多詞典都有。
不過,原項目在最後的部分有個我尚未完全理解的式子:
MAP (ゃ)(ャ)
按照手冊的說法,Use parenthesized groups for character sequences (eg. for composed Unicode characters):
(使用括號包裹的分組來處理由多個字符組成的特殊字符,比如 Unicode 中的那些特殊符號),所以這幾條規則應該是針對拗音 —— 對於チョロチョロ
,計算機使用チ
、ョ
、ロ
這 3 個字符來表示,所以替換的時候,需要專門一起替換麼?但是我並不認讀懂
另外,下面這樣的規則似乎並沒有什麼意義,因為很多字典都沒有收錄腕きゞ
這樣的詞條,替不替換其實無所謂。要真想解決踊り字導致的問題可能還是得借助正則表達式才可以(哼哼,我就是在嘚瑟~《日本語非辭書形辭典 v3》在上個版本已經完美支持啦)
MAP (ゝ)(ヽ)
MAP (ゞ)(ヾ)
(這樣可能看不出來,找圖片看得更清楚,第一列的符號都有個小勾)
REP#
下面介紹與 MAP 規則很像的 REP 規則:
REP 12
REP かけ 掛け
REP かか 掛か
(原項目寫的是REP かけ 掛け かけ
,可能是寫錯了……)
和 MAP 一樣,REP 12
說明接下來會有 12 條 REP 規則,但和 MAP 不一樣的是,REP かけ 掛け
的かけ
是輸入,掛け
才是替換的結果(和 MAP 的順序是反過來的),另外,REP 規則可以實現多個字符的替換。(用製表符來分割參數,而 MAP 只能使用()
局限性比較大)
aff 基本格式#
接下來回過頭來介紹 aff 文件的基本格式,所有的 aff 文件都應該是下面這樣開頭:
SET UTF-8
LANG ja
FLAG long
# https://github.com/MrCorn0-0/hunspell_ja_JP/
SET
設定文件編碼;
LANG
指定規則適用的語言,其他語言請參考手冊;
FLAG long
指的是給規則命名時需要使用 2 個 ASCII 碼的字符,比如後面會用來當做例子的一個規則,XA 就是規則名。:
SFX XA Y 1
SFX XA い く い
如果喜歡用數字直接給規則編號,可以按照手冊的:The long' value sets the double extended ASCII character flag type, the num' sets the decimal number flag type.
,在文件的開頭寫FLAG num
,之後就可以按下面這樣的風格起名了:
# 形容詞く
SFX 001 Y 1
SFX 001 い く い
為了方便以後修改,用數字命名時最好通過註釋進行解釋說明。注意:#
要放在每一行的開頭,所在的那一行才會被當做解釋說明的內容。
不過通過數字命名還會導致一個問題:如何對一個單詞同時使用多個規則呢?(用言的活用都不是一種對吧?)
如果使用long
我們只需要把規則直接寫上去就可以了(長度都是固定的 2 個字符,程序可以識別):
高い/XAXB
使用數字時就需要用英文半角逗號來區分:
高い/001,002
SFX#
之所以要回過頭去介紹 aff 文件最開始部分的寫法,主要是想強調 dic 文件可以指定多種規則,這裡的多種規則不是指的 MAP 和 REP,而是接下來介紹的支持自定義命名的 SFX 規則。
這裡專門強調 “支持自定義命名”,是因為命名不僅會影響 aff 文件,還會影響 dic 文件。
一開始就提到了 dic 文件中可能會出現這樣的寫法:
高い/XA
在某種程度來說,SFX 規則才是真正意義上的構詞法,通過這個功能可以構造詞綴、實現詞形還原,才能實現日語活用的推導與辭書形的還原。(接下來的內容主要參考手冊的AFFIX FILE OPTIONS FOR AFFIX CREATION
章節部分。)
首先,還是以一個簡單的例子進行說明:
SFX XA Y 1
SFX XA い く い
第一行:XA
是我們自定義的詞綴的名字,Y 是固定的參數(手冊裡有談到,1 是這個名為XA
的詞綴包含的詞綴數量;
第二行,第一个い
表示這條規則只對dic
文件中的以い
結尾的單詞起作用(手冊的說法是stripping characters from beginning (at prefix rules) or end (at suffix rules) of the word
,我的理解是我們定義了一個名為 XA 的詞綴,詞綴的真正內容是い
。這個詞綴就是程序處理時會處理的部分),く
表示這條規則將在輸入的單詞以く
結尾時發揮作用,末尾的い
表示構詞法真正發揮作用前還需要滿足的條件:“構詞法推導的單詞結尾是い”,不滿足的話,不會展示推導結果。
舉個具體的例子,當我們輸入高く
時,程序將く
替換為い
(這裡的い是第二行的第一個い),然後查找 dic 文件中以い
結尾單詞是否有高い
(這裡的以い結尾是因為第二行的第二個い),如果有,那麼 GoldenDict 就會直接跳到相應的界面。
之所以說簡單,是因為原項目中這條規則其實是下面這樣:
#形容詞文く
SFX XA Y 2
SFX XA し く/BaTe し
SFX XA い く/BaTe い
這是因為日語中高く
還可以繼續活用,所以用戶可能劃詞的部分是高くば
或者高くて
,原項目作者充分考慮了日語的這個特點,使用/
這條規則來處理嵌套的連續變形(是不是有點眼熟?因為在 dic 文件中,這個符號是用來表示單詞可以用於哪些規則,你可以理解為詞性)。
需要注意的是,BaTe
是 2 條獨立的規則,是原作者自定義的,查閱原項目的 aff 文件就可以找到:
SFX Ba Y 1
SFX Ba 0 ば .
(我不是很確定是否有高くば
這樣的語法,但我將這條規則剝離出來進行測試時,發現這條規則確實會讓軟件在輸入高くば
時展示高い
的解釋)
SFX Te Y 3
SFX Te 0 て [っいしく]
SFX Te 0 で ん
SFX Te 0 て .
(關鍵就是SFX Te 0 て .
這一句,其他是規則從日語語法的角度來說和 SFX XA し く/BaTe し
、SFX XA い く/BaTe い
無關,原項目作者可能是出於個人習慣將他們歸為一類)
這裡出現了.
這樣極為特殊字符,之前說過,它們所在的位置應該是表示替換後的結果中詞尾應該包含的字符,而這個位置的參數有一個規則是Zero condition is indicated by dot.
,所以SFX Te 0 て .
的意思是對於任何處於詞尾的て
直接將其刪除。
這樣說可能很難理解規則的作用,我們回到SFX XA い く/BaTe い
這個規則,把它和SFX Te 0 て .
放到一起再舉一個例子就好理解了:原項目作者是為了處理輸入高くて
。(去掉/BaTe
的話,就和《日本語非辭書形辭典》一樣:對於劃詞的要求變高了,所以原項目真的設計得非常好)
上面的例子由於涉及到了雙重嵌套,可能還是不好理解,有疑問的話,參考手冊的Twofold suffix stripping
章節和AFFIX FILE OPTIONS FOR AFFIX CREATION
部分。其實我也沒有怎麼搞懂啦
下面再舉一個例子:
SFX To Y 1
SFX To 0 とも .
To
是規則名,0
代表這條規則會刪掉定義的詞綴とも
,とも
表示實際輸入的單詞的詞綴, .
表示對於替換後結果沒有任何要求,所以這條名為To
的規則作用是:去掉輸入框中輸入的位於詞尾的とも
。(這條規則很符合學習とも
這條日語規則的思維,所以也許會好理解一點吧。)
另外,SFX Te 0 て [っいしく]
這裡出現了[っいしく]
,按照手冊的說法
這表示替換之前輸入的字符中要有っ、い、し、く中的任意一個。
下面還有一些比較難的自定義規則,只做簡單介紹:
[^行]く
和正則表達式的意思一樣,規則只對那些不含行く、但又以い結尾的單詞生效
SFX 5T く い/TeTaTrTm [^行]く
SFX 5T く っ/TeTaTrTm 行く
這條規則就是稍微長了 “一” 點,實際沒什麼特殊的
SFX KN く け/RUTeTaTrTmf1f2f3f4f5f6m0m1m2m3m4m5m6m7TiTItiSuNgQq1Eba1M1myo く
這個規則其實可以拆成 2 條,但原作者靈活運用了[]
的語法
SFX xU い かる/bs [しじ]い
題外話#
本人會對構詞法感興趣完全是因為《日本語非辭書形辭典》項目遇到了棘手的問題,想看看有沒有其他解決的思路,所以才會花近一周的時間閱讀晦澀難懂的手冊。雖然只了解大概,但已經感受到 GoldenDict 的構詞法 Hunspell 功能的強大之處語言學 YYDS!,抱著授人以魚不如授人以漁的想法分享自己的總結希望能讓大家對這個功能有點了解,也期待大家能一起完善 GoldenDict 的構詞法 Hunspell 功能。快去 - hunspell_ja_JP提交 issue 和 PR 吧
不過還有個更重要的原因:才加入 FreeMdict 的 @epistularum 用類似《日本語非辭書形辭典》的思路做了個 GoldenDict 構詞法的 Demo(在 GitHub),為了與 Ta 溝通交流,我才下定決心把拖了幾個月的事情給正式提上日程(英語不好真的是舉步維艱……)
另外,提前預告一下 GoldenDict 可以輕鬆解決曾經提到過的日語複合動詞漢字書寫的問題啦:
另外,很奇怪的是 GoldenDict 的 hunspell 功能可以返回多個結果,歐路詞典也有類似的 hunspell 的功能,但卻只支持返回一個結果。雖然按照手冊說法只有一個特性在手機上可能不受支持BUG: UTF-8 flag type doesn't work on ARM platform.
,但歐路不會因為這個原因不採用這項技術吧……
但不論如何,都應該支持多個拼寫結果才對,比如:
雨が降ります。
バスから降ります。
歐路詞典的類似功能#
和FreeMdict Forum的壇友討論了下歐路詞典的類似功能:
大的優化沒有發現,小的優化還是存在的:
- 有一些遺漏的句型,比如
言わざるを得ない
的言わざる
(但劃言わ
也會有結果) - 口語表達ん、と、ちゃ等等
Hunspell 技術似乎只能解決 2 重嵌套,所以我估計像食べたければ
這種繁複的句型可能解決不了(也就是說劃詞之前還是要想好,不可能真的哪裡不會點哪裡)
另外,我可能沒有表述清楚:歐路是有 “還原活用” 的功能,但技術不太像是 Hunspell:
(多重嵌套,原項目疑似做不到)
(單獨劃到詞尾,原項目可以)
忽略了日語的書寫習慣
形容詞連最簡單的變形都不支持
從結果來看,歐路可能是專門做了一個不开源的活用推導工具,但不允許用戶自定義,所以試試向歐路官方反應,讓他們補充完善吧
參考#
教程#
-
- 最關鍵的就是名為 man 4 hunspell 文件,其他文件是介紹 Linux 端實現的技術細節
- 提供一份我的批註版:
-
向德語系學生介紹 hunspell - 許一諾的文章 - 知乎
- 整理了上面用到 man 4 hunspell PDF 資料,講解了一些簡單的概念
開源項目#
- MrCorn0-0/hunspell_ja_JP: Hunspell morphology dictionary for Japanese used in GoldenDict. (github.com):按照日語語法的思路寫了將近 400 條構詞法規則,作者是一位中國人
- epistularum/hunspell-ja-deinflection: Hunspell dictionary to deinflect all Japanese conjugated verbs to the dictionary form and suggest correct spelling. (github.com):按照替換詞尾的思路寫規則,不是很完善,作者是一名外國人
- https://github.com/wooorm/dictionaries:收錄了 JavaScript 寫的構詞法,但沒有日語
相關#
注:本文在如下平台有備份:
以 hunspell_ja_JP 項目文件為例淺析 goldendict 構詞法規則 - NoHeartPen 的文章 - 知乎
以 hunspell_ja_JP 項目文件為例淺析 goldendict 構詞法規則 - 軟件經驗交流展望 - FreeMdict Forum