Java 漢字轉拼音(解決多音字問題)

jopen 9年前發布 | 64K 次閱讀 Java Java開發

    上一篇文章 Java 漢字轉拼音 介紹了Java 中利用Pinyin4j 實現漢字轉拼音,但是對于多音字問題采取的是組合拼音方式,例如長沙 取拼音結果就是 changsha zhangsha。某些情況下我們希望能得到多音字的唯一拼音,此時就需要借助多音字字典了,原理很簡單:給多音字一個默認的拼音并告訴計算機碰到哪些詞的時候使用其它的拼音,例如 長 字,我們可以給它指定默認拼音為 zhang,并標識 長沙 拼音為 chang。


以上是自己搜集的一個多音字詞典 duoyinzi_pinyin.txt

    a#阿  
    ao#拗  
    ai#艾  
    bang#膀 磅 蚌  
    ba#扒車 扒拉 扒皮  
    bai#叔伯 百 柏楊  
    bao#剝皮 薄  暴 堡 曝  
    beng#蚌埠  
    bi#復辟  臂  秘魯 泌陽  
    bing#屏棄 屏氣 屏除 屏退 屏息  
    bian#扁 便  
    bo#薄荷 單薄 伯 伯爵  泊 波 柏 蘿卜 孛  
    bu#卜  
    can#參  
    cang#藏  
    cen#參差  
    ceng#曾 噌  
    cha#差 剎那 寶剎 一剎 查  
    chai#公差 差役 專差 官差 聽差 美差 辦差 差事 差使 肥差 當差 欽差 苦差 出差  
    chan#顫 單于 禪  
    chang#長  廠  
    chao#朝 嘲  
    che#工尺 車  
    chen#稱職 勻稱 稱心 相稱 對稱  
    cheng#稱 乘 澄 噌吰 橙 秤  
    chu#畜  
    chui#椎心  
    chuan#傳  
    chi#匙 尺 吃  
    chong#重慶 重重 蟲  
    chou#臭  
    chuang#經幢  
    chuo#綽  
    ci#參差 伺  龜茲  
    cuan#攢錢 攢聚 攢動   
    cuo#撮兒 撮要 撮合  
    da#大 嗒  
    dao#叨  
    dai#大夫  
    dan#單 彈  
    dang#鐺  
    de#的  
    di#堤 底 怎的 有的 目的 標的 打的 的確 的當 的士 地 提防  
    diao#藍調 調調 音調 論調 格調 調令 低調 筆調 基調 強調 聲調 濫調 老調 色調 單調 腔調 跑調 曲調 步調 語調 主調 情調  
    ding#丁  
    du#讀 都 度  
    dou#全都 句讀  
    duo#舵 測度 忖度 揣度 猜度  
    dun#糧囤 盾 頓 沌 敦  
    e#阿諛 阿膠 阿彌 惡心  
    er#兒  
    fan#番  
    feng#馮  
    fo#佛  
    fu#仿佛 果脯 罘  
    fou#否則 否定 應否 是否 與否 否決  
    ga#咖喱 伽馬  
    gai#蓋  
    gao#告  
    gang#扛鼎  
    ge#革 蛤蚧 文蛤 蛤蜊 咯  
    gei#給  
    geng#脖頸  
    gong#女紅  
    gu#谷 中鵠  鼓  
    gui#龜 柜 硅  
    gua#呱  
    guan#綸巾 東莞  
    guang#廣  
    ha#蛤  
    hai#還 嗨  
    hao#貉子 貉絨  
    hang#夯 總行 分行 支行 行業 排行 行情 央行 商行 外行 銀行 商行 酒行 麻行 琴行 巷道  
    he#和 合 核  
    heng#道行  
    hu#鵠 水滸  
    hua#滑  
    huan#歸還 放還 奉還  
    hui#會 澮河  
    hong#紅 虹  
    huo#軟和 熱和 暖和  
    ji#病革 給養 自給 給水 薪給 給予 供給 稽 緝 藉 奇數 亟 詰屈 薺菜  
    jia#雪茄 伽 家 價 賈  
    jian#見  
    jiang#降  
    jiao#嚼舌 嚼子 細嚼 角 剿 餃 腳 蕉 矯  
    jie#解 慰藉 蘊藉 詰  
    jin#矜 勁  
    jing#頸 景  
    ju#咀嚼  居 桔 句  
    jun#均  
    juan#棚圈 圈養  
    jv#咀嚼 趑趄  
    jvan#豬圈 羊圈  
    jue#主角 角色 旦角 女角 丑角 角力 名角 配角 咀嚼 覺  
    jun#龜裂 俊  
    jvn#龜裂  
    ka#咖 卡 喀  
    kai#楷  
    kang#扛 扛活 扛大  
    ke#咳 殼  
    keng#吭  
    kuai#會計 財會 澮  
    kuo#括  
    la#癩痢 臘  
    lai#癩瘡 癩子 癩蛤 癩皮  
    lao#積潦 絡子 落枕 落價 粩 姥  
    le#樂 勒 了  
    lei#勒緊  
    lo#然咯  
    lou#佝僂  
    long#里弄 弄堂 瀧  
    li#躒  
    liao#了解 了結  明了 了得 末了 未了 了如  了如指掌 潦  
    liang#靚 倆  
    liu#六  
    lu#碌 陸 露  
    luo#絡 絡 落 漯  
    lv#率 綠  
    lun#綸  
    mai#埋  
    man#埋怨 蔓  
    mai#脈  
    mang#氓 芒  
    mao#冒  
    meng#群氓 盟  
    mei#沒  
    mo#埋沒 隱沒 脈脈 模 摩  
    mou#綢繆 牟  
    mi#秘 泌尿 分泌 謎  
    miu#謬 謬論 紕繆  
    mu#人模 字模 模板 模樣 模具 裝模 裝模做樣 模子  
    na#哪 娜 那  
    nan#南  
    ne#哪吒 呢  
    nong#弄  
    ni#毛呢 花呢 呢絨 線呢 呢料 呢子 呢喃 溺  
    niao#尿 鳥  
    nian#粘  
    niang#釀  
    niu#執拗 拗不  
    nu#努  
    nue#瘧 瘧疾  
    nuo#婀娜 裊娜  
    nv#女  
    nve#瘧原 瘧蚊  
    o#喔  
    pa#扒  
    pai#派 迫擊 迫擊炮  
    pao#刨 炮  
    pang#胖 膀胱 膀腫 磅礴  
    pi#辟 否極 臧否 龍陂 芘  
    pian#扁舟 便宜  
    piao#樸姓  
    ping#屏 蘋  
    po#湖泊 血泊  迫 樸刀 坡 陂  
    pu#暴十 一曝十寒 里堡 十里堡 脯 樸 曝曬 瀑 埔  
    qi#期 其 泣  
    qiu#龜茲  
    qi#稽首 緝鞋 棲  奇 漆 齊  
    qia#卡脖 卡子 關卡 卡殼 哨卡 邊卡 發卡  
    qiao#雀盲 雀子 地殼 甲殼 軀殼  
    qian#纖 乾  
    qiang#強  
    qie#茄 趔趄   
    qin#親 沁  
    qing#干親 親家  
    qu#區 趣  
    quan#圈 券  
    que#雀  
    ruo#若  
    sai#塞  
    se#堵塞 搪塞 茅塞 閉塞 鼻塞 梗塞 阻塞 淤塞 擁塞 哽塞  色  
    sha#莎 剎車 急剎 急剎車 廈  
    shai#色子  
    shao#勺  
    shan#姓單 單縣 杉  
    shang#衣裳  
    she#拾級 折本 射 蛇  
    shen#沙參 野參 參王 人參 紅參 丹參 山參 海參 刺參 鹿參 什 身 沈  
    sheng#野乘 千乘 史乘  省 晟 盛  
    shi#鑰匙 拾荒 撿拾 拾物 家什 什物 什錦 麻什  麥什 喀什 牛什  識 似的 食 石 氏 拾 適  
    shuai#表率 率性 率直 率真 粗率 率領 輕率 直率 草率 大率 坦率 衰  
    shuang#瀧水  
    shu#屬 數 術 熟  
    shui#游說  
    shuo#數見 數見不鮮  說  
    si#窺伺 伺弄 伺機 似 思  
    su#宿  
    sui#尿泡  
    ta#拓本 拓片 碑拓 疲沓 拖沓 雜沓 沓 塔 鴻塔  
    tang#湯  
    tao#陶  
    tan#彈性 彈力 反彈  
    ti#提 體  
    tiao#調  
    ting#町 聽  
    tui#褪  
    tuo#拓  
    tun#囤 屯  
    wei#尾 蔚 圩  
    wu#無 可惡 交惡 好惡 厭惡 憎惡 嫌惡 痛惡 深惡  
    wan#藤蔓 枝蔓 瓜蔓 蔓兒  莞  萬 百萬 皖  
    wai#崴  
    xia#蝦 嚇 夏  
    xi#棲棲 系  蹊 洗 溪 戲  
    xiao#校 切削 削面 刀削 刮削  
    xian#纖細 光纖 纖巧 纖柔 纖小 纖維 纖瘦 纖纖 化纖 纖秀 棉纖 纖塵  
    xiang#降 巷  
    xie#解數 出血 采血 換血 血糊 尿血 淤血 放血 血暈 血淋 便血 吐血 咯血 葉韻 蝎 蝎子 邪  
    xiu#銅臭 乳臭 成宿 星宿  
    xin#馨 信 鴻信  
    xing#深省 省視 內省 不省人事 省悟 省察 行 旅行 例行 行程 行樂 龍行 人行 流行 先行 行星 品行  發行 行政 風行 龍行 龍行 麟行 滎  
    xu#牧畜 畜產 畜牧 畜養 吁 麥埂圩 滸  
    xue#削  血  
    xun#蕁 尋  
    ya#琊  
    yao#鑰匙 金鑰 耀 曜  
    yan#咽  殷紅 腌 煙  
    ye#液 抽咽 哽咽 咽炎 下咽 嗚咽 幽咽 悲咽 葉  葉  
    yi#自艾 遺 屹  
    yin#殷  
    ying#滎經  
    yo#杭育  
    yong#涌  
    yu#余 呼吁 吁請 吁求 育 熨帖 熨燙 於  
    yuan#員  
    yun#熨  
    yue#約 樂音 器樂 樂律 樂章 音樂 樂理 民樂 樂隊 聲樂 奏樂 弦樂 樂壇 管樂 配樂 樂曲 樂譜  鎖鑰 密鑰 樂團 樂器  
    za#綁扎 結扎 包扎 捆扎 咱家  
    zan#攢 咱  
    zang#寶藏 藏歷 藏文 藏語 藏青 藏族 藏醫  藏藥 藏藍 西藏  
    zai#牛仔 龜仔 龍仔 鼻仔 羊仔  仔仔 麻仔  麵包仔 麥旺仔 鴻仔 煲仔 福仔  
    ze#擇  
    zeng#曾孫 曾祖  
    zong#綜  
    zha#扎  
    zhai#宅  
    zhan#不粘 粘貼 粘連  
    zhao#朝朝 明朝 朝暉 朝夕 朝思 有朝 今朝 朝氣 朝三 朝秦 朝霞 鷹爪 龍爪 魔爪 爪牙 失著 著數 龍爪槐  
    zhe#折 著  
    zhi#標識 吱 殖 枝  
    zhong#重 種  
    zhou#粥  
    zhu#屬意 著  
    zhua#爪子  
    zhui#椎 隹  
    zhuo#執著 著裝 著落 著意 著力 附著 著筆 膠著 著手 著重 穿著 衣著 執著 著眼 著墨 著實 沉著 著陸 著想 著色  
    zhuang#幢房 一幢 幢樓  
    zi#仔 茲  
    zu#足  
    zuo#柞  
    zui#咀  

自己封裝了一個獲取漢字拼音 全拼和簡拼的工具類 PinyinUtils,代碼如下:

    package com.ricky.java.suggestion.util;

import java.io.BufferedReader;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.UnsupportedEncodingException;  
import java.util.HashMap;  
import java.util.Map;  

import org.apache.log4j.Logger;  

import net.sourceforge.pinyin4j.PinyinHelper;  
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;  
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;  
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;  
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;  
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;  

public class PinyinUtils {  

    private static final Logger logger = Logger.getLogger("devLog");  

    public static Map<String,String> dictionary = new HashMap<String,String>();  

    //加載多音字詞典  
    static{  

        BufferedReader br = null;  
        try {  
            File file = new File("./config/duoyinzi_pinyin.txt");  
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));  

            String line = null;  
            while((line=br.readLine())!=null){  

                String[] arr = line.split("#");  

                if(StringUtils.isNotEmpty(arr[1])){  
                    String[] sems = arr[1].split(" ");  
                    for (String sem : sems) {  

                        if(StringUtils.isNotEmpty(sem)){  
                            dictionary.put(sem , arr[0]);  
                        }  
                    }  
                }  
            }  

        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally{  
            if(br!=null){  
                try {  
                    br.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  

    }  

    public static String[] chineseToPinYin(char chineseCharacter) throws BadHanyuPinyinOutputFormatCombination{  
        HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();  
        outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);  
        outputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);  
        outputFormat.setVCharType(HanyuPinyinVCharType.WITH_V);  

        if(chineseCharacter>=32 && chineseCharacter<=125){    //ASCII >=33 ASCII<=125的直接返回 ,ASCII碼表:http://www.asciitable.com/  
            return new String[]{String.valueOf(chineseCharacter)};  
        }  

        return PinyinHelper.toHanyuPinyinStringArray(chineseCharacter, outputFormat);  
    }  

    /** 
     * 獲取漢字拼音的全拼 
     * @param chineseCharacter 
     * @return 
     * @throws BadHanyuPinyinOutputFormatCombination 
     */  
    public static String chineseToPinYinF(String chineseCharacter) throws BadHanyuPinyinOutputFormatCombination{  
        if(StringUtils.isEmpty(chineseCharacter)){  
            return null;  
        }  

        char[] chs = chineseCharacter.toCharArray();  

        StringBuilder result = new StringBuilder();  

        for(int i=0;i<chs.length;i++){  
            String[] arr = chineseToPinYin(chs[i]);  
            if(arr==null){  
                result.append("");  
            }else if(arr.length==1){  
                result.append(arr[0]);  
            }else if(arr[0].equals(arr[1])){  
                result.append(arr[0]);  
            }else{  

                String prim = chineseCharacter.substring(i, i+1);  
//              System.out.println("prim="+prim+"**i="+i);  

                String lst = null,rst = null;  

                if(i<=chineseCharacter.length()-2){  
                    rst = chineseCharacter.substring(i,i+2);  
                }  
                if(i>=1 && i+1<=chineseCharacter.length()){  
                    lst = chineseCharacter.substring(i-1,i+1);  
                }  

//              System.out.println("lst="+lst+"**rst="+rst);  

                String answer = null;  
                for (String py : arr) {  

                    if(StringUtils.isEmpty(py)){  
                        continue;  
                    }  

                    if((lst!=null && py.equals(dictionary.get(lst))) ||  
                            (rst!=null && py.equals(dictionary.get(rst)))){  
                        answer = py;  
//                      System.out.println("get it,answer="+answer+",i="+i+"**break");  
                        break;  
                    }  

                    if(py.equals(dictionary.get(prim))){  
                        answer = py;  
//                      System.out.println("get it,answer="+answer+",i="+i+"**prim="+prim);  
                    }  
                }  
                if(answer!=null){  
                    result.append(answer);  
                }else{  
                    logger.warn("no answer ch="+chs[i]);  
                }  
            }  
        }  

        return result.toString().toLowerCase();  
    }  

    public static String chineseToPinYinS(String chineseCharacter) throws BadHanyuPinyinOutputFormatCombination{  
        if(StringUtils.isEmpty(chineseCharacter)){  
            return null;  
        }  

        char[] chs = chineseCharacter.toCharArray();  

        StringBuilder result = new StringBuilder();  

        for(int i=0;i<chs.length;i++){  
            String[] arr = chineseToPinYin(chs[i]);  
            if(arr==null){  
                result.append("");  
            }else if(arr.length==1){  
                result.append(arr[0].charAt(0));  
            }else if(arr[0].equals(arr[1])){  
                result.append(arr[0].charAt(0));  
            }else{  

                String prim = chineseCharacter.substring(i, i+1);  
//              System.out.println("prim="+prim+"**i="+i);  

                String lst = null,rst = null;  

                if(i<=chineseCharacter.length()-2){  
                    rst = chineseCharacter.substring(i,i+2);  
                }  
                if(i>=1 && i+1<=chineseCharacter.length()){  
                    lst = chineseCharacter.substring(i-1,i+1);  
                }  

//              System.out.println("lst="+lst+"**rst="+rst);  

                String answer = null;  
                for (String py : arr) {  

                    if(StringUtils.isEmpty(py)){  
                        continue;  
                    }  

                    if((lst!=null && py.equals(dictionary.get(lst))) ||  
                            (rst!=null && py.equals(dictionary.get(rst)))){  
                        answer = py;  
//                      System.out.println("get it,answer="+answer+",i="+i+"**break");  
                        break;  
                    }  

                    if(py.equals(dictionary.get(prim))){  
                        answer = py;  
//                      System.out.println("get it,answer="+answer+",i="+i+"**prim="+prim);  
                    }  
                }  
                if(answer!=null){  
                    result.append(answer.charAt(0));  
                }else{  
                    logger.warn("no answer ch="+chs[i]);  
                }  
            }  
        }  

        return result.toString().toLowerCase();  
    }  

}  </pre><br />

測試代碼

    package com.ricky.java.suggestion.test;

import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;  

import com.ricky.java.suggestion.util.PinyinUtils;  

public class PinyinTest {  

    /** 
     * @param args 
     */  
    public static void main(String[] args) {  

        try {  

//          String str = "長沙綠愛旅行";  
            String str = "中信銀行(長沙旅行社分行)";  

            System.out.println(str+" pyf="+PinyinUtils.chineseToPinYinF(str));  
            System.out.println(str + " pys="+PinyinUtils.chineseToPinYinS(str));  

        } catch (BadHanyuPinyinOutputFormatCombination e) {  
            e.printStackTrace();  
        }  
    }  

}  </pre><br />

來自:http://blog.csdn.net/top_code/article/details/39641615

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!