怎么設(shè)置“智能(陳橋)五筆”為默認(rèn)輸入法?
(點(diǎn)擊上方公眾號(hào),可快速關(guān)注)
作者:我是小茗同學(xué)
鏈接:www.cnblogs.com/liuxianan/p/pinyinjs.html
前言
網(wǎng)上關(guān)于JS實(shí)現(xiàn)漢字和拼音互轉(zhuǎn)的文章很多,但是比較雜亂,都是互相抄來(lái)抄去,而且有的不支持多音字,有的不支持聲調(diào),有的字典文件太大,還比如有時(shí)候我僅僅是需要獲取漢字拼音首字母卻要引入200kb的字典文件,無(wú)法根據(jù)實(shí)際需要滿(mǎn)足需求。
綜上,我精心整理并修改了網(wǎng)上幾種常見(jiàn)的字典文件并簡(jiǎn)單封裝了一下可以直接拿來(lái)用的工具庫(kù)。
這篇文章差不多一個(gè)月前就寫(xiě)好了大部分了,但是就差拼音輸入法這一塊一直沒(méi)時(shí)間去弄(與其說(shuō)是沒(méi)時(shí)間,還不如說(shuō)是本人太懶),所以一直拖到今天才發(fā)表。
代碼和DEMO演示
github項(xiàng)目地址:https://github.com/liuxianan/pinyinjs
完整demo演示:https://demo.liuxianan.com/pinyinjs/
帶多音字識(shí)別的演示:https://demo.liuxianan.com/pinyinjs/polyphone.html
漢字轉(zhuǎn)拼音:
帶詞庫(kù)的識(shí)別多音字的漢字轉(zhuǎn)拼音:
拼音轉(zhuǎn)漢字(簡(jiǎn)單的拼音輸入法):
關(guān)于多音字
鑒于很多人都比較關(guān)心多音字的問(wèn)題,所以單獨(dú)拿出一個(gè)小章節(jié)來(lái)介紹多音字的相關(guān)問(wèn)題。
準(zhǔn)確識(shí)別各種復(fù)雜語(yǔ)句中混雜的多音字其實(shí)并沒(méi)有那么容易,有兩個(gè)關(guān)鍵的地方,一個(gè)是多音字詞庫(kù)的豐富程度,一個(gè)是能否正確的給語(yǔ)句進(jìn)行分詞。而詞庫(kù)和分詞的實(shí)現(xiàn)都需要一個(gè)非常豐富的詞典文件,現(xiàn)代漢語(yǔ)詞語(yǔ)有多少個(gè),估計(jì)沒(méi)有人算得清,再加上每天新出現(xiàn)的人名、網(wǎng)絡(luò)詞語(yǔ)、科技詞語(yǔ)等等。一個(gè)普通的詞庫(kù)文件至少也有幾百kb,所以不太適合web環(huán)境下去實(shí)現(xiàn),一般最好放在服務(wù)器端做成一個(gè)接口。
鑒于很多人都希望有多音字識(shí)別的功能,所以我簡(jiǎn)單實(shí)現(xiàn)了一個(gè)版本。詞庫(kù)文件是從這里找到的,并根據(jù)實(shí)際情況將文件從1.8M壓縮到了912kb,分詞暫時(shí)只是自己非常簡(jiǎn)單的實(shí)現(xiàn)(也可以說(shuō)壓根就沒(méi)有分詞),如果是服務(wù)器端推薦幾個(gè)不錯(cuò)的中文分詞工具:Python版的Jieba和NodeJieba,性能非常好,其它語(yǔ)言版的參考上面項(xiàng)目的README。
關(guān)于分詞,摘抄一段網(wǎng)絡(luò)解釋?zhuān)?/p>
詞是最小的能夠獨(dú)立活動(dòng)的有意義的語(yǔ)言成分,英文單詞之間是以空格作為自然分界符的,而漢語(yǔ)是以字為基本的書(shū)寫(xiě)單位,詞語(yǔ)之間沒(méi)有明顯的區(qū)分標(biāo)記,因此,要對(duì)中文信息進(jìn)行處理,正確的分詞就顯得尤為關(guān)鍵。
比如看中國(guó)這一個(gè)詞,單獨(dú)的看中讀kàn zhòng,中國(guó)讀zhōng guó,連在一起卻讀作kàn zhōng guó。
我這個(gè)實(shí)現(xiàn)非常得簡(jiǎn)單,效果一般,性能也一般,需要下載將近1M的詞庫(kù)文件,所以不適合web環(huán)境,演示地址:
https://demo.liuxianan.com/pinyinjs/polyphone.html
漢字與拼音相關(guān)知識(shí)普及 漢字范圍
一般認(rèn)為Unicode編碼中的漢字范圍是 /^[\u2E80-\u9FFF]+$/(11904-40959),但是其中有很多不是漢字,或者說(shuō)是可以讀的漢字,本文用到的幾個(gè)字典文件的漢字范圍均是 /^[\u4E00-\u9FA5]+$/,也就是(19968-40869),另外還有一個(gè)單獨(dú)的漢字〇,其Unicode位置是12295。
拼音組合
漢字有21個(gè)聲母:b, p, m, f, d, t, n, l, g, k, h, j, q, x, zh, ch, sh, r, z, c, s,24個(gè)韻母,其中單韻母有6個(gè):a, o, e, i, u, v, 復(fù)韻母有18個(gè):ai , ei, ui , ao, ou, iu , ie, ve, er, an , en , in, un , vn , ang, eng, ing , ong,假設(shè)聲母和韻母兩兩組合的話(huà),會(huì)有24X21=504種組合,實(shí)際情況是有些組合是沒(méi)有意義的,比如bv, gie, ve等,去除這部分后,還剩余412種。
拼音字典文件
按照字典文件的大小從小到大依次介紹。
字典一:拼音首字母
該字典文件的內(nèi)容大致如下:
/**
* 拼音首字母字典文件
*/
varpinyin_dict_firstletter= {};
pinyin_dict_firstletter.all= "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJG...";
pinyin_dict_firstletter.polyphone= {"19969":"DZ","19975":"WM","19988":"QJ","20048":"YL",...};
該數(shù)據(jù)字典將Unicode字符中4E00(19968)-9FA5(40869)共計(jì)20902個(gè)漢字的拼音首字母拼接在一起得到一個(gè)很長(zhǎng)的字符串,然后再將有多音字的漢字(共計(jì)370個(gè)多音字)單獨(dú)列出來(lái)。該字典文件大小為25kb。
該字典文件優(yōu)點(diǎn)是體積小,支持多音字,缺點(diǎn)是只能獲取拼音首字母。
字典二:常用漢字
該字典文件將漢字按照拼音進(jìn)行歸類(lèi),共計(jì)401種組合,收錄了6763個(gè)常用漢字,不支持多音字。由于從網(wǎng)絡(luò)上收集的,收錄字?jǐn)?shù)較少,所以文件體積只有24kb,后續(xù)有空看能不能給擴(kuò)充一下。
字典文件大致內(nèi)容如下(這里只是示例,所以只展示一小部分):
/**
* 常規(guī)拼音數(shù)據(jù)字典,收錄常見(jiàn)漢字6763個(gè),不支持多音字
*/
varpinyin_dict_notone=
{
"a":"啊阿錒",
"ai":"埃挨哎唉哀皚癌藹矮艾礙愛(ài)隘誒捱噯嗌嬡璦曖砹锿靄",
"an":"鞍氨安俺按暗岸胺案諳埯揞犴庵桉銨鵪頇黯",
"ang":"骯昂盎",
"ao":"凹敖熬翱襖傲奧懊澳坳拗嗷噢岙廒遨媼驁聱螯鏊鰲鏖",
"ba":"芭捌扒叭吧笆八疤巴拔跋靶把耙壩霸罷爸茇菝萆捭岜灞杷鈀粑鲅魃",
"bai":"白柏百擺佰敗拜稗薜掰鞴",
"ban":"斑班搬扳般頒板版扮拌伴瓣半辦絆阪坂豳鈑瘢癍舨",
"bang":"邦幫梆榜膀綁棒磅蚌鎊傍謗蒡螃",
"bao":"苞胞包褒雹保堡飽寶抱報(bào)暴豹鮑爆勹葆宀孢煲鴇褓趵齙",
"bo":"剝薄玻菠播撥缽波博勃搏鉑箔伯帛舶脖膊渤泊駁亳蕃啵餑檗擘礴鈸鵓簸跛",
"bei":"杯碑悲卑北輩背貝鋇倍狽備憊焙被孛陂邶埤蓓唄怫悖碚鵯褙鐾",
"ben":"奔苯本笨畚坌錛"
// 省略其它
};
后來(lái)慢慢發(fā)現(xiàn)這個(gè)字典文件中存在諸多錯(cuò)誤,比如把虐的拼音寫(xiě)成了nue(正確寫(xiě)法應(yīng)該是nve),躺寫(xiě)成了thang,而且不支持多音字,所以后來(lái)我根據(jù)其它字典文件自己重新生成了一份這樣格式的 字典文件:
共有404種拼音組合
收錄了6763個(gè)常用漢字
支持多音字
不支持聲調(diào)
文件大小為27kb
同時(shí),我根據(jù)網(wǎng)上一份常用6763個(gè)漢字使用頻率表,將這6763個(gè)漢字按照使用頻率進(jìn)行了排序,這樣就可以實(shí)現(xiàn)一個(gè)差強(qiáng)人意的JS版輸入法了。
另外,根據(jù)另外一份更完整的字典文件發(fā)現(xiàn)其實(shí)共有412種拼音組合,上面字典文件中沒(méi)有出現(xiàn)的8種發(fā)音是:
chua,den,eng,fiao,m,kei,nun,shei
字典三:終極字典
首先,從網(wǎng)上找的如下結(jié)構(gòu)字典文件(下面稱(chēng)為字典A),具體是哪不記得了,支持聲調(diào)和多音字,它將Unicode字符中4E00(19968)-9FA5(40869)共計(jì)20902個(gè)漢字(如果算上〇的話(huà)那就是20903個(gè))拼音全部列舉,該字典文件大小為280kb:
3007(ling2)
4E00(yi1)
4E01(ding1,zheng1)
4E02(kao3)
4E03(qi1)
4E04(shang4,shang3)
4E05(xia4)
4E06(none0)
4E07(wan4,mo4)
4E08(zhang4)
4E09(san1)
4E0A(shang4,shang3)
4E0B(xia4)
4E0C(ji1)
4E0D(bu4,bu2,fou3)
4E0E(yu3,yu4,yu2)
4E0F(mian3)
4E10(gai4)
4E11(chou3)
4E12(chou3)
4E13(zhuan1)
4E14(qie3,ju1)
...
其中,對(duì)于沒(méi)有或者找不到讀音的漢字,統(tǒng)一標(biāo)注為none0,我統(tǒng)計(jì)了一下,這樣的漢字一共有525個(gè)。
本著將字典文件盡可能減小體積的目標(biāo),發(fā)現(xiàn)上述文件中除了第一個(gè)〇(3007)之外,其它都是連續(xù)的,所以我把它改成了如下結(jié)構(gòu),文件體積也從280kb減小到了117kb:
varpinyin_dict_withtone= "yi1,ding1 zheng1,kao3,qi1,shang4 shang3,xia4,none0,wan4 mo4,zhang4,san1,shang4 shang3,xia4,ji1,bu4 bu2 fou3,yu3 yu4 yu2,mian3,gai4,chou3,chou3,zhuan1,qie3 ju1...";
該字典文件的缺點(diǎn)是聲調(diào)是用數(shù)字標(biāo)出的,如果想要得出類(lèi)似xiǎo míng tóng xué這樣的拼音的話(huà),需要一個(gè)算法將合適位置的字母轉(zhuǎn)換成āáǎàōóǒòēéěèīíǐìūúǔùüǖǘǚǜńň。
本來(lái)還準(zhǔn)備自己嘗試寫(xiě)一個(gè)轉(zhuǎn)換的方法的,后來(lái)又找到了如下字典文件(下面稱(chēng)為字典B),它收錄了20867個(gè)漢字,也支持聲調(diào)和多音字,但是聲調(diào)是直接標(biāo)在字母上方的,由于它將漢字也列舉出來(lái),所以文件體積比較大,有327kb,大致內(nèi)容如下:
{
"吖": "yā,ā",
"阿": "ā,ē",
"呵": "hē,a,kē",
"嗄": "shà,á",
"啊": "ā,á,ǎ,à,a",
"腌": "ā,yān",
"錒": "ā",
"錒": "ā",
"矮": "ǎi",
"愛(ài)": "ài",
"挨": "āi,ái",
"哎": "āi",
"礙": "ài",
"癌": "ái",
"艾": "ài",
"唉": "āi,ài",
"藹": "ǎi"
/* 省略其它 */
}
但是經(jīng)過(guò)比對(duì),發(fā)現(xiàn)有502個(gè)漢字是字典A中讀音為none但是字典B中有讀音的,還有21個(gè)漢字是字典A中有但是B中沒(méi)有的:
{
"兙": "shí kè",
"兛": "qiān",
"兝": "fēn",
"兞": "máo",
"兡": "bǎi kè",
"兣": "lǐ",
"唞": "dǒu",
"嗧": "jiā lún",
"囍": "xǐ",
"堎": "lèng líng",
"猤": "hú",
"瓩": "qián wǎ",
"礽": "réng",
"膶": "rùn",
"芿": "rèng",
"蟘": "tè",
"貣": "tè",
"釀": "niàng niàn niáng",
"醸": "niàng",
"鋱": "tè",
"鋱": "tè"
}
還有7個(gè)漢字是B中有但是A中沒(méi)有的:
{
"?": "lēng",
"?": "léng",
"?": "léng",
"?": "lèng",
"?": "lèng,lì,lìn",
"?": "réng",
"?": "niàng"
}
所以我在字典A的基礎(chǔ)上將二者進(jìn)行了合并,得到了最終的字典文件 pinyin_dict_withtone.js,文件大小為122kb:
varpinyin_dict_withtone="yī,dīng zhēng,kǎo qiǎo yú,qī,shàng,xià,hǎn,wàn mò,zhàng,sān,shàng shǎng,xià,qí jī...";
如何使用
我將這幾種字典文件放在一起并簡(jiǎn)單封裝了一下解析方法,使用中可以根據(jù)實(shí)際需要引入不同字典文件。
封裝好的3個(gè)方法:
/**
* 獲取漢字的拼音首字母
* @param str 漢字字符串,如果遇到非漢字則原樣返回
* @param polyphone 是否支持多音字,默認(rèn)false,如果為true,會(huì)返回所有可能的組合數(shù)組
*/
pinyinUtil.getFirstLetter(str,polyphone);
/**
* 根據(jù)漢字獲取拼音,如果不是漢字直接返回原字符
* @param str 要轉(zhuǎn)換的漢字
* @param splitter 分隔字符,默認(rèn)用空格分隔
* @param withtone 返回結(jié)果是否包含聲調(diào),默認(rèn)是
* @param polyphone 是否支持多音字,默認(rèn)否
*/
pinyinUtil.getPinyin(str,splitter,withtone,polyphone);
/**
* 拼音轉(zhuǎn)漢字,只支持單個(gè)漢字,返回所有匹配的漢字組合
* @param pinyin 單個(gè)漢字的拼音,不能包含聲調(diào)
*/
pinyinUtil.getHanzi(pinyin);
下面分別針對(duì)不同場(chǎng)合如何使用作介紹。
如果你只需要獲取拼音首字母
< type="text/java"src="pinyin_dict_firstletter.js"></>
< type="text/java"src="pinyinUtil.js"></>
< type="text/java">
pinyinUtil.getFirstLetter('小茗同學(xué)');// 輸出 XMTX
pinyinUtil.getFirstLetter('大中國(guó)',true);// 輸出 ['DZG', 'TZG']
</>
需要特別說(shuō)明的是,如果你引入的是其它2個(gè)字典文件,也同樣可以獲取拼音首字母的,只是說(shuō)用這個(gè)字典文件更適合。
如果拼音不需要聲調(diào)
< type="text/java"src="pinyin_dict_notone.js"></>
< type="text/java"src="pinyinUtil.js"></>
< type="text/java">
pinyinUtil.getPinyin('小茗同學(xué)');// 輸出 'xiao ming tong xue'
pinyinUtil.getHanzi('ming');// 輸出 '明名命鳴銘冥茗溟酩瞑螟暝'
</>
如果需要聲調(diào)或者需要處理生僻字
< type="text/java"src="pinyin_dict_withtone.js"></>
< type="text/java"src="pinyinUtil.js"></>
< type="text/java">
pinyinUtil.getPinyin('小茗同學(xué)');// 輸出 'xiǎo míng tóng xué'
pinyinUtil.getPinyin('小茗同學(xué)','-',true,true);// 輸出 ['xiǎo-míng-tóng-xué', 'xiǎo-míng-tòng-xué']
</>
如果需要精準(zhǔn)識(shí)別多音字
由于詞典文件較大,本示例不推薦在web環(huán)境下使用:
< type="text/java"src="dict/pinyin_dict_withtone.js"></>
< type="text/java"src="dict/pinyin_dict_polyphone.js"></>
< type="text/java"src="pinyinUtil.js"></>
< type="text/java">
pinyinUtil.getPinyin('長(zhǎng)城和長(zhǎng)大',' ',true,true);// 輸出:cháng chéng hé zhǎng dà
pinyinUtil.getPinyin('喝水和喝彩',' ',true,true);// 輸出:hē shuǐ hé hè cǎi
pinyinUtil.getPinyin('偉大的大夫',' ',true,true);// 輸出:wěi dà de dài fū
</>
關(guān)于簡(jiǎn)單拼音輸入法
一個(gè)正式的輸入法需要考慮的東西太多太多,比如詞庫(kù)、用戶(hù)個(gè)人輸入習(xí)慣等,這里只是實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的輸入法,沒(méi)有任何詞庫(kù)(雖然加上也可以,但是web環(huán)境不適合引入太大的文件)。
推薦使用第二個(gè)字典文件pinyin_dict_notone.js,雖然字典三字?jǐn)?shù)更多,但是不能按照漢字使用頻率排序,一些生僻字反而在前面。
<link rel="stylesheet"type="text/css"href="simple-input-method/simple-input-method.css">
<input type="text"class="163e-8670-7ab1-0d97 test-input-method"/>
< type="text/java"src="pinyin_dict_notone.js"></>
< type="text/java"src="pinyinUtil.js"></>
< type="text/java"src="simple-input-method/simple-input-method.js"></>
< type="text/java">
SimpleInputMethod.init('.test-input-method');
</>
結(jié)語(yǔ)
由于本工具類(lèi)的目標(biāo)環(huán)境是web,而web注定了文件體積不能太大,所以不能引入太大的詞庫(kù)文件,由于沒(méi)有詞庫(kù)的支持,所以多音字無(wú)法識(shí)別,實(shí)現(xiàn)的拼音輸入法也無(wú)法智能地匹配出合適的詞語(yǔ),需要詞庫(kù)支持的可以參考這個(gè)nodejs環(huán)境下的項(xiàng)目:https://github.com/hotoo/pinyin
關(guān)注「前端大全」
看更多精選前端技術(shù)文章
↓↓↓
轉(zhuǎn)載請(qǐng)注明來(lái)自夕逆IT,本文標(biāo)題:《怎么設(shè)置“智能(陳橋)五筆”為默認(rèn)輸入法?》

還沒(méi)有評(píng)論,來(lái)說(shuō)兩句吧...