Java 汉字转拼音(解决多音字问题)

jopen 9年前

    上一篇文章 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();            }                        }  

测试代码
    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();                }            }                }  

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