上篇博客中我们确定了搜索建议的具体方案,该方案中涉及到一个将汉字转换为拼音的问题.这里我们主要讲解这个问题.使用pinyin4j来完成.

1 . jar获取方式:
maven
<!-- 拼音 -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>
或者 直接从我的百度云中下载
链接:http://pan.baidu.com/s/1dDZzoOT 密码:1eai

2. 下载解压后的目录结构及说明如下

  • doc : pinyin4j的api文档
  • lib : pinyin4j的jar包
  • src : pinyin4j的源代码
  • CHANGELOG.txt : pinyin4j的版本更新日志
  • COPYING.txt : LICENSE说明
  • README.txt : pinyin4j的概要介绍

3.   源码解析

net/sourceforge/pinyin4j

ChineseToPinyinResource:读取/pinyindb/unicode_to_hanyu_pinyin.txt

GwoyeuRomatzyhResource:读取/pinyindb/pinyin_gwoeu_mapping.xml

GwoyeuRomatzyhTranslator:汉语拼音转换为Gwoyeu拼音

PinyinRomanizationResource:读取/pinyindb/pinyin_mapping.xml

PinyinRomanizationType:定义汉语拼音的六种类型 (pinyin4j支持将汉字转化成六种拼音表示法。其对应关系是:汉语拼音-Hanyu Pinyin,通用拼音-Tongyong Pinyin, 威妥玛拼音(威玛拼法)-Wade-Giles  Pinyin, 注音符号第二式-MPSII Pinyin, 耶鲁拼法-Yale Pinyin和国语罗马字-Gwoyeu Romatzyh)

PinyinRomanizationTranslator:拼音转换,convertRomanizationSystem(源拼音字符串,源拼音类型,目标拼音类型)

PinyinFormatter:汉语拼音格式化(如:根据提供的格式格式化拼音字符串;注音标等方法)

PinyinHelper:音标格式化方法类(六种拼音类型的获取方法等)

ResourceHelper:从classpath路径下读取文件流BufferedInputStream

TextHelper:获取汉语拼音中拼音或音调数字

extractToneNumber返回音调数字,如输入:luan4 返回:4

extractPinyinString返回汉语拼音前的拼音,如输入:luan4 返回:luan

/format

HanyuPinyinCaseType:定义汉语拼音大小写类型(控制生成的拼音是以大写方式显示还是以小写方式显示)

  • LOWERCASE :guó
  • UPPERCASE :GUÓ

HanyuPinyinToneType:定义汉语拼音声调类型

  • WITH_TONE_NUMBER(以数字代替声调) :  zhong1  zhong4
  • WITHOUT_TONE (无声调) :             zhong   zhong
  • WITH_TONE_MARK (有声调) :           zhōng  zhòng

HanyuPinyinVCharType:定义汉语拼音字符u的类型(碰到unicode 的ü 、v 和 u时的显示方式)

  • WITH_U_AND_COLON : lu:3
  • WITH_V :            lv3
  • WITH_U_UNICODE :    lü3

HanyuPinyinOutputFormat:拼音格式类型构造类

/exception  异常类

BadHanyuPinyinOutputFormatCombination:拼音格式化组合错误异常,如一下组合:

LOWERCASE-WITH_V-WITH_TONE_MARK   LOWERCASE-WITH_U_UNICODE-WITH_TONE_MARK

UPPERCASE-WITH_V-WITH_TONE_MARK   UPPERCASE-WITH_U_UNICODE-WITH_TONE_MARK

其主要思路:

1)先通过汉字字符的unicode编码从unicode_to_hanyu_pinyin.txt找到对应的带声调数字的拼音

2)根据给定的输出格式化要求对该带声调的数字拼音进行格式化处理

3)在各个拼音之间可以相互转换:

根据pinyin_mapping.xml可以找到汉语拼音对应其他四种格式,如:

<item>
  <Hanyu>a</Hanyu>
  <Wade>a</Wade>
  <MPSII>a</MPSII>
  <Yale>a</Yale>
  <Tongyong>a</Tongyong>
 </item>

根据pinin_gwoyeu_mapping.xml可以找出汉语拼音与Gwoyeu不同声调对应的格式,如:

<item>
  <Hanyu>a</Hanyu>
  <Gwoyeu_I>a</Gwoyeu_I>
  <Gwoyeu_II>ar</Gwoyeu_II>
  <Gwoyeu_III>aa</Gwoyeu_III>
  <Gwoyeu_IV>ah</Gwoyeu_IV>
  <Gwoyeu_V>.a</Gwoyeu_V>
 </item>

4.  字符串转化成拼音Java代码示例

工具类
public class Pinyin4jUtil { /*** 汉字转换位汉语拼音首字母,英文字符不变,特殊字符丢失 支持多音字,生成方式如(长沙市长:cssc,zssz,zssc,cssz)* * 这个方法不太符合我创建索引的要求---我要的是数组--自己重建一个* @param chines*            汉字* @return 拼音 字符串*/ public static String converterToFirstSpell(String chines) { return parseTheChineseByObject(discountTheChinese(MinMethod(chines).toString())); } /*** * @描述:返回类型调整为数组* @param chines* @return* @return String[]* @exception* @createTime:2016年3月22日* @author: songqinghu*/public static Set<String> converterToFirstSpellToSet(String chines){return parseTheChineseByObjectToSet(discountTheChinese(MinMethod(chines).toString())); }/*** * @描述:获取首字母方法抽取* @param chines* @return* @return StringBuffer* @exception* @createTime:2016年3月22日* @author: songqinghu*/public static StringBuffer MinMethod(String chines){StringBuffer pinyinName = new StringBuffer(); char[] nameChar = chines.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < nameChar.length; i++) { if (nameChar[i] > 128) { //char中1-127对应特殊字符和数字,字母try { // 取得当前汉字的所有全拼 String[] strs = PinyinHelper.toHanyuPinyinStringArray( nameChar[i], defaultFormat); if (strs != null) { for (int j = 0; j < strs.length; j++) { // 取首字母 pinyinName.append(strs[j].charAt(0)); if (j != strs.length - 1) { pinyinName.append(","); } } } // else { // pinyinName.append(nameChar[i]); // } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pinyinName.append(nameChar[i]); } pinyinName.append(" "); } return pinyinName;}/*** 汉字转换位汉语全拼,英文字符不变,特殊字符丢失* 支持多音字,生成方式如(重当参:zhongdangcen,zhongdangcan,chongdangcen* ,chongdangshen,zhongdangshen,chongdangcan)*  不符合 我的要求---重新写一个返回值为Set<String>类型* @param chines*            汉字* @return 拼音*/ public static String converterToSpell(String chines) { // return pinyinName.toString(); return parseTheChineseByObject(discountTheChinese(midConoverterToSpell(chines).toString())); } /*** * @描述:返回值为set* @param chines* @return* @return Set<String>* @exception* @createTime:2016年3月22日* @author: songqinghu*/public static Set<String> converterToSpellToSet(String chines){return parseTheChineseByObjectToSet(discountTheChinese(midConoverterToSpell(chines).toString())); }/*** @描述:方法抽取* @param chines* @return* @return StringBuffer* @exception* @createTime:2016年3月22日* @author: songqinghu*/private  static StringBuffer midConoverterToSpell(String chines){StringBuffer pinyinName = new StringBuffer(); char[] nameChar = chines.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < nameChar.length; i++) { if (nameChar[i] > 128) { try { // 取得当前汉字的所有全拼 String[] strs = PinyinHelper.toHanyuPinyinStringArray( nameChar[i], defaultFormat); if (strs != null) { for (int j = 0; j < strs.length; j++) { pinyinName.append(strs[j]); if (j != strs.length - 1) { pinyinName.append(","); } } } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pinyinName.append(nameChar[i]); } pinyinName.append(" "); } return pinyinName;}/*** 去除多音字重复数据* * @param theStr* @return*/ private static List<Map<String, Integer>> discountTheChinese(String theStr) { // 去除重复拼音后的拼音列表 List<Map<String, Integer>> mapList = new ArrayList<Map<String, Integer>>(); // 用于处理每个字的多音字,去掉重复 Map<String, Integer> onlyOne = null; String[] firsts = theStr.split(" "); // 读出每个汉字的拼音 for (String str : firsts) { onlyOne = new Hashtable<String, Integer>(); String[] china = str.split(","); // 多音字处理 for (String s : china) { Integer count = onlyOne.get(s); if (count == null) { onlyOne.put(s, new Integer(1)); } else { onlyOne.remove(s); count++; onlyOne.put(s, count); } } mapList.add(onlyOne); } return mapList; } /*** 解析并组合拼音,对象合并方案(推荐使用)* * @return*/ private static String parseTheChineseByObject( List<Map<String, Integer>> list) { Map<String, Integer> first = MinparseTheChineseByObject(list);String returnStr = ""; if (first != null) { // 遍历取出组合字符串 for (String str : first.keySet()) { returnStr += (str + ","); } } if (returnStr.length() > 0) { returnStr = returnStr.substring(0, returnStr.length() - 1); } return returnStr; } /*** 解析并组合拼音,对象合并方案(推荐使用)---返回set<String>* * @return*/ private static  Set<String> parseTheChineseByObjectToSet( List<Map<String, Integer>> list) { Map<String, Integer> first = MinparseTheChineseByObject(list);Set<String> result = null; if (first != null && first.keySet().size()>0) { // 遍历取出组合字符串 result = first.keySet();} return result; } /*** * @描述:方法抽取* @param list* @return* @return Map<String,Integer>* @exception* @createTime:2016年3月22日* @author: songqinghu*/private static Map<String,Integer> MinparseTheChineseByObject(List<Map<String, Integer>> list){Map<String, Integer> first = null; // 用于统计每一次,集合组合数据 // 遍历每一组集合 for (int i = 0; i < list.size(); i++) { // 每一组集合与上一次组合的Map Map<String, Integer> temp = new Hashtable<String, Integer>(); // 第一次循环,first为空 if (first != null) { // 取出上次组合与此次集合的字符,并保存 for (String s : first.keySet()) { for (String s1 : list.get(i).keySet()) { String str = s + s1; temp.put(str, 1); } } // 清理上一次组合数据 if (temp != null && temp.size() > 0) { first.clear(); } } else { for (String s : list.get(i).keySet()) { String str = s; temp.put(str, 1); } } // 保存组合数据以便下次循环使用 if (temp != null && temp.size() > 0) { first = temp; } } return first;}}

方法Demo

    public static void addDocumentAndPY() throws SolrServerException, Exception{SolrClient solrClient = new  HttpSolrClient("http://localhost:8983/solr/group");Collection<SolrInputDocument> docs  = new ArrayList<SolrInputDocument>();List<String> words = new ArrayList<String>();words.add("测试");int i = 0;for (String word : words) {SolrInputDocument doc = new SolrInputDocument();doc.addField("groupId", i+"");doc.addField("categoryName", word);//需要对工具类进行改写--返回的是多值的时候需要进行数组的切分 确保可以使用 xxx* 进行匹配Set<String> lengths = Pinyin4jUtil.converterToSpellToSet(word);Set<String> shorts = Pinyin4jUtil.converterToFirstSpellToSet(word);for (String py : shorts) {doc.addField("pinyin", py);}for (String py : lengths) {doc.addField("pinyin", py);}i++;docs.add(doc);System.out.println(word + " length : " + lengths + " shorts: "+ shorts);}solrClient.add(docs);System.out.println("索引建立结束");}

最后截图留念:

solr入门之搜索建议的拼音转换工具相关推荐

  1. Python 汉字转拼音库 pypinyin, 附:汉字拼音转换工具

    一.初衷: 一些开源软件的配置文件中识别区分的部分用英文,那么我们在批量生成配置文件的时候,可以从CMDB导入汉字(idc_name), 然后将它转换成拼音,再或者拼接上IP地址,以便更准确的识别.例 ...

  2. Android 拼音转换工具PinyinUtils

    1.首先下载pinyin4j-2.5.0.jar,拷贝到工程的lib目录里 2.创建工具类:PinyinUtils /*** 拼音转换工具* * @描述 TODO* @项目名称 App_imooc* ...

  3. java分词支持拼音_java 支持分词的高性能拼音转换工具,速度是 pinyin4j 的两倍...

    pinyin pinyin 是 java 实现的高性能中文拼音转换工具. 创作目的 想为 java 设计一款便捷易用的拼音工具. 特性 极简的 api 设计 支持转换长文本 支持多音字 支持多种拼音标 ...

  4. java分词支持拼音_java 支持分词的高性能拼音转换工具,速度是 pinyin4j

    pinyin pinyin 是 java 实现的高性能中文拼音转换工具. 创作目的 想为 java 设计一款便捷易用的拼音工具. 特性 极简的 api 设计 支持转换长文本 支持多音字 支持多种拼音标 ...

  5. java 中文分词转拼音_java 支持分词的高性能拼音转换工具, 速度是 pinyin4j 的两倍...

    java 支持分词的高性能拼音转换工具, 速度是 pinyin4j 的两倍 pinyin https://github.com/houbb/pinyin 是 java 实现的高性能中文拼音转换工具. ...

  6. C# 拼音转换-工具类

    /// <summary>/// 拼音转换工具/// </summary>public class PinYinHelper{public static PingYinMode ...

  7. java 分词器耗时 性能_java 支持分词的高性能拼音转换工具,速度是 pinyin4j 的两倍...

    pinyin pinyin 是 java 实现的高性能中文拼音转换工具. 创作目的 想为 java 设计一款便捷易用的拼音工具. 特性 极简的 api 设计 支持转换长文本 支持多音字 支持多种拼音标 ...

  8. android 字体像素转换工具类_Android开发之拼音转换工具类PinyinUtils示例

    本文实例讲述了Android开发之拼音转换工具类PinyinUtils.分享给大家供大家参考,具体如下: 1.首先下载pinyin4j-2.5.0.jar,拷贝到工程的lib目录里 或者点击此处本站下 ...

  9. js 汉字拼音转换工具。

    github地址 npm npm install pinyin 用法 var pinyin = require("pinyin");console.log(pinyin(" ...

最新文章

  1. 内核驱动模块Makfle
  2. 03-25实验一、命令解释程序的编写
  3. java自学手记——继承
  4. Pycharm下载 安装 和谐 与 卸载
  5. Python常见十六个错误集合,你知道那些?
  6. 在图形中使用指定字体
  7. SAP 电商云 Spartacus UI shipping method 切换时的 spinner 显示
  8. java压缩图片等比缩放_java对图片进行压缩和resize缩放的方法
  9. php7 phpunit,Make phpunit catch php7 TypeError
  10. 前端-requests-flask对应关系 HTTPBasicAuth
  11. 战不胜抖音的腾讯微视,即将被判“死刑”? | 畅言
  12. Silverlight 4 的打印支持
  13. TCP和UPD的理解
  14. 单片机学习(点阵LED及多模块同时实现)
  15. 夺命雷公狗—玩转SEO---38---百度快照投诉从而更新快照
  16. 数据分析面试手册《指标篇》
  17. 深度学习超分辨率综述阅读笔记(翻译)
  18. linux基础(五)----linux命令系统学习----系统管理命令
  19. 华为OD机试 - 德州扑克(Java JS Python)
  20. java中关于包的描述_下列关于Java包的描述中,错误的是() (1.0分)_学小易找答案

热门文章

  1. 2022“航天宏图杯”遥感影像耕地变化检测第四名方案简介
  2. 网络基础(四) — QUIC协议
  3. c语言求矩阵各行元素之和
  4. 搭建easy-mock数据模拟服务器
  5. sas数据操作update、modify by ke=、控制modify的更新、datasets添加约束条件、操作文件变动aduit trail...
  6. Linux内核源码高速下载地址
  7. ubuntu系统搭建steam饥荒联机服务器
  8. 什么是CHIP LAN片式网络变压器?片式网络变压器分哪几种?目前应用较多的是哪种片式结构?
  9. 一本通-1414:成绩
  10. 软件测试中UT,IT,ST,UAT