JavaScript 漢字與拼音互轉終極方案 附JS拼音輸入法
前言
網上關於JS實現漢字和拼音互轉的文章很多,但是比較雜亂,都是互相抄來抄去,而且有的不支援多音字,有的不支援聲調,有的字典檔案太大,還比如有時候我僅僅是需要獲取漢字拼音首字母卻要引入200kb的字典檔案,無法根據實際需要滿足需求。
綜上,我精心整理並修改了網上幾種常見的字典檔案並簡單封裝了一下可以直接拿來用的工具庫。
程式碼和DEMO演示
github專案地址:https://github.com/liuxianan/pinyinjs
完整demo演示:http://demo.liuxianan.com/pinyinjs/
漢字轉拼音:
拼音轉漢字:
漢字與拼音相關知識普及
漢字範圍
一般認為Unicode編碼中的漢字範圍是 /^[\u2E80-\u9FFF]+$/
(11904-40959),但是其中有很多不是漢字,或者說是可以讀的漢字,本文用到的幾個字典檔案的漢字範圍均是 /^[\u4E00-\u9FA5]+$/
,也就是(19968-40869),另外還有一個單獨的漢字〇,其Unicode位置是12295。
拼音組合
漢字有21個聲母:b, p, m, f, d, t, n, l, g, k, h, j, q, x, zh, ch, sh, r, z, c, s,24個韻母,其中單韻母有6個:a, o, e, i, u, v, 複韻母有18個:ai , ei, ui , ao, ou, iu , ie, ve, er, an , en , in, un , vn , ang, eng, ing , ong,假設聲母和韻母兩兩組合的話,會有24X21=504種組合,實際情況是有些組合是沒有意義的,比如bv, gie, ve等,去除這部分後,還剩餘412種。
拼音字典檔案
按照字典檔案的大小從小到大依次介紹。
字典一:拼音首字母
該字典檔案的內容大致如下:
/** * 拼音首字母字典檔案 */ var pinyin_dict_firstletter = {}; pinyin_dict_firstletter.all = "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJG..."; pinyin_dict_firstletter.polyphone = {"19969":"DZ","19975":"WM","19988":"QJ","20048":"YL",...};
該資料字典將Unicode字元中4E00
(19968)-9FA5
(40869)共計20902個漢字的拼音首字母拼接在一起得到一個很長的字串,然後再將有多音字的漢字(共計370個多音字)單獨列出來。該字典檔案大小為25kb
。
該字典檔案優點是體積小,支援多音字,缺點是隻能獲取拼音首字母。
字典二:常用漢字
該字典檔案將漢字按照拼音進行歸類,共計401種組合,收錄了6763個常用漢字,不支援多音字。由於從網路上收集的,收錄字數較少,所以檔案體積只有24kb,後續有空看能不能給擴充一下。
字典檔案大致內容如下(這裡只是示例,所以只展示一小部分):
/** * 常規拼音資料字典,收錄常見漢字6763個,不支援多音字 */ var pinyin_dict_notone = { "a":"啊阿錒", "ai":"埃挨哎唉哀皚癌藹矮艾礙愛隘誒捱噯嗌嬡璦曖砈鑀靄", "an":"鞍氨安俺按暗岸胺案諳垵揞犴庵桉銨鵪頇黯", "ang":"骯昂盎", "ao":"凹敖熬翱襖傲奧懊澳坳拗嗷噢嶴廒遨媼驁聱螯鏊鰲鏖", "ba":"芭捌扒叭吧笆八疤巴拔跋靶把耙壩霸罷爸茇菝萆捭岜灞杷鈀粑鮁魃", "bai":"白柏百擺佰敗拜稗薜掰鞴", "ban":"斑班搬扳般頒板版扮拌伴瓣半辦絆阪阪豳鈑瘢癍舨", "bang":"邦幫梆榜膀綁棒磅蚌鎊傍謗蒡螃", "bao":"苞胞包褒雹保堡飽寶抱報暴豹鮑爆勹葆宀孢煲鴇褓趵齙", "bo":"剝薄玻菠播撥缽波博勃搏鉑箔伯帛舶脖膊渤泊駁亳蕃啵餑檗擘礴鈸鵓簸跛", "bei":"杯碑悲卑北輩背貝鋇倍狽備憊焙被孛陂邶埤蓓唄怫悖碚鵯褙鐾", "ben":"奔苯本笨畚坌錛" // 省略其它 };
後來慢慢發現這個字典檔案中存在諸多錯誤,比如把虐
的拼音寫成了nue
(正確寫法應該是nve),躺
寫成了thang
,而且不支援多音字,所以後來我根據其它字典檔案自己重新生成了一份這樣格式的 字典檔案:
- 共有404種拼音組合
- 收錄了6763個常用漢字
- 支援多音字
- 不支援聲調
- 檔案大小為27kb
同時,我根據網上一份常用6763個漢字使用頻率表,將這6763個漢字按照使用頻率進行了排序,這樣就可以實現一個差強人意的JS版輸入法了。
另外,根據另外一份更完整的字典檔案發現其實共有412種拼音組合,上面字典檔案中沒有出現的8種發音是:
chua,den,eng,fiao,m,kei,nun,shei
字典三:終極字典
首先,從網上找的如下結構字典檔案(下面稱為字典A),具體是哪不記得了,支援聲調和多音字,它將Unicode字元中4E00
(19968)-9FA5
(40869)共計20902個漢字(如果算上〇的話那就是20903個)拼音全部列舉,該字典檔案大小為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) ...
其中,對於沒有或者找不到讀音的漢字,統一標註為none0
,我統計了一下,這樣的漢字一共有525個。
本著將字典檔案儘可能減小體積的目標,發現上述檔案中除了第一個〇(3007)之外,其它都是連續的,所以我把它改成了如下結構,檔案體積也從280kb
減小到了117kb
:
var pinyin_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...";
該字典檔案的缺點是聲調是用數字標出的,如果想要得出類似xiǎo míng tóng xué
這樣的拼音的話,需要一個演算法將合適位置的字母轉換成āáǎàōóǒòēéěèīíǐìūúǔùüǖǘǚǜńň
。
本來還準備自己嘗試寫一個轉換的方法的,後來又找到了如下字典檔案(下面稱為字典B),它收錄了20867個漢字,也支援聲調和多音字,但是聲調是直接標在字母上方的,由於它將漢字也列舉出來,所以檔案體積比較大,有327kb
,大致內容如下:
{ "吖": "yā,ā", "阿": "ā,ē", "呵": "hē,a,kē", "嗄": "shà,á", "啊": "ā,á,ǎ,à,a", "醃": "ā,yān", "錒": "ā", "錒": "ā", "矮": "ǎi", "愛": "ài", "挨": "āi,ái", "哎": "āi", "礙": "ài", "癌": "ái", "艾": "ài", "唉": "āi,ài", "藹": "ǎi" /* 省略其它 */ }
但是經過比對,發現有502個漢字是字典A中讀音為none
但是字典B中有讀音的,還有21個漢字是字典A中有但是B中沒有的:
{ "兙": "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個漢字是B中有但是A中沒有的:
{ "㘄": "lēng", "䉄": "léng", "䬋": "léng", "䮚": "lèng", "䚏": "lèng,lì,lìn", "㭁": "réng", "䖆": "niàng" }
所以我在字典A的基礎上將二者進行了合併,得到了最終的字典檔案pinyin_dict_withtone.js,檔案大小為122kb
:
var pinyin_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ī...";
如何使用
我將這幾種字典檔案放在一起並簡單封裝了一下解析方法,使用中可以根據實際需要引入不同字典檔案。
封裝好的3個方法:
/** * 獲取漢字的拼音首字母 * @param str 漢字字串,如果遇到非漢字則原樣返回 * @param polyphone 是否支援多音字,預設false,如果為true,會返回所有可能的組合陣列 */ pinyinUtil.getFirstLetter(str, polyphone); /** * 根據漢字獲取拼音,如果不是漢字直接返回原字元 * @param str 要轉換的漢字 * @param splitter 分隔字元,預設用空格分隔 * @param withtone 返回結果是否包含聲調,預設是 * @param polyphone 是否支援多音字,預設否 */ pinyinUtil.getPinyin(str, splitter, withtone, polyphone); /** * 拼音轉漢字,只支援單個漢字,返回所有匹配的漢字組合 * @param pinyin 單個漢字的拼音,不能包含聲調 */ pinyinUtil.getHanzi(pinyin);
下面分別針對不同場合如何使用作介紹。
如果你只需要獲取拼音首字母
<script type="text/javascript" src="pinyin_dict_firstletter.js"></script> <script type="text/javascript" src="pinyinUtil.js"></script> <script type="text/javascript"> pinyinUtil.getFirstLetter('小茗同學'); // 輸出 XMTX pinyinUtil.getFirstLetter('大中國', true); // 輸出 ['DZG', 'TZG'] </script>
需要特別說明的是,如果你引入的是其它2個字典檔案,也同樣可以獲取拼音首字母的,只是說用這個字典檔案更適合。
如果拼音不需要聲調
<script type="text/javascript" src="pinyin_dict_noletter.js"></script> <script type="text/javascript" src="pinyinUtil.js"></script> <script type="text/javascript"> pinyinUtil.getPinyin('小茗同學'); // 輸出 'xiao ming tong xue' pinyinUtil.getHanzi('ming'); // 輸出 '明名命鳴銘冥茗溟酩瞑螟暝' </script>
如果需要聲調或者需要處理生僻字
<script type="text/javascript" src="pinyin_dict_withletter.js"></script> <script type="text/javascript" src="pinyinUtil.js"></script> <script type="text/javascript"> pinyinUtil.getPinyin('小茗同學'); // 輸出 'xiǎo míng tóng xué' pinyinUtil.getPinyin('小茗同學', '-', true, true); // 輸出 ['xiǎo-míng-tóng-xué', 'xiǎo-míng-tòng-xué'] </script>
關於簡單拼音輸入法
一個正式的輸入法需要考慮的東西太多太多,比如詞庫、使用者個人輸入習慣等,這裡只是實現一個最簡單的輸入法,沒有任何詞庫(雖然加上也可以,但是web環境不適合引入太大的檔案)。
推薦使用第二個字典檔案pinyin_dict_noletter.js
,雖然字典三字數更多,但是不能按照漢字使用頻率排序,一些生僻字反而在前面。
<link rel="stylesheet" type="text/css" href="simple-input-method/simple-input-method.css"> <input type="text" class="test-input-method"/> <script type="text/javascript" src="pinyin_dict_noletter.js"></script> <script type="text/javascript" src="pinyinUtil.js"></script> <script type="text/javascript" src="simple-input-method/simple-input-method.js"></script> <script type="text/javascript"> SimpleInputMethod.init('.test-input-method'); </script>
結語
由於本工具類的目標環境是web,而web註定了檔案體積不能太大,所以不能引入太大的詞庫檔案,由於沒有詞庫的支援,所以多音字無法識別,實現的拼音輸入法也無法智慧地匹配出合適的詞語,需要詞庫支援的可以參考這個nodejs環境下的專案:https://github.com/hotoo/pinyin
相關文章
- JS 漢字轉換拼音JS
- js漢字轉換為拼音功能JS
- 漢字轉拼音pl/sqlSQL
- C#漢字轉漢語拼音C#
- js 漢字按照拼音排序效果JS排序
- C#中漢字轉拼音C#
- iOS漢字轉拼音的方法iOS
- JavaScript按照漢字拼音順序排序JavaScript排序
- js 漢字陣列按拼音排序JS陣列排序
- JavaPinyin4j(漢字轉拼音)JavaAPI
- php 漢字轉換成拼音 程式PHP
- xpinyin:漢字轉換為拼音庫
- php獲取漢字的拼音 拼音首字母PHP
- Python 漢字轉拼音的庫--- PyPinyinPython
- oracle 外部表 漢字轉換為拼音Oracle
- ThinkPHP 漢字轉成多種形式拼音PHP
- js將漢字轉換為拼音程式碼例項JS
- C#漢字拼音檢索C#
- 漢字之美,拼音之韻
- python3實現漢字轉拼音Python
- win11微軟拼音輸入法變繁體字微軟
- ubuntu 配置拼音輸入法步驟Ubuntu
- win10系統微軟拼音輸入法打字不顯示漢字怎麼辦Win10微軟
- Hanlp漢字轉拼音使用python呼叫詳解HanLPPython
- 厭煩了搜狗輸入法我轉向谷歌拼音谷歌
- win10拼音打不出漢字怎麼辦 win10電腦輸入法打不出漢字如何解決Win10
- C# 漢字轉拼音 使用微軟的Visual Studio International Pack 類庫提取漢字拼音首字母C#微軟
- JS 中文轉拼音JS
- ORACLE SQL函式中文漢字轉拼音首字母OracleSQL函式
- [轉]SQL獲取漢字拼音首字母函式SQL函式
- mysql按照漢字拼音進行order by排序MySql排序
- 怎麼刪除微軟拼音輸入法win10_win10如何解除安裝微軟拼音輸入法微軟Win10
- Fedora23如何安裝fcitx拼音輸入法?Fedora23安裝fcitx拼音輸入法教程
- 使用HMM實現簡單拼音輸入法HMM
- oralce中漢字轉為拼音首字母的函式(轉)函式
- Linux Mint 18安裝sougou拼音輸入法LinuxGo
- Debian下安裝拼音輸入法Fcitx
- Fedora 18安裝google輸入法和雲拼音Go