谈谈我做拼音搜索的一点经验

需要注意的一些事情

本文使用的为 Java 语言解决方案。

搜索方法上,按照个人理解,有两点关键:

  • 分词
    将类似 "women" 这样的词分解成 "wo'men"。经过这样的分词,在搜索时无论通过全拼音匹配,还是首字母匹配,处理起来都比较方便。

  • 词库构建
    目前我接触过的常见搜索场景有两种,它们对词库的建立有如下影响:

  1. 通讯录搜索
    对词库有频繁的添加 / 删除操作。

  2. 站内搜索
    使用预先维护好的词库。

如果是通讯录搜索,可以在新建联系人的时候,把联系人的名字转为拼音,存入数据库中另一个记录拼音的字段,在搜索的时候通过拼音来匹配。
如果是站内搜索,可以直接建立拼音词库,搜索的时候通过拼音来匹配。

实现

首先是词库的构建。毫无疑问,我们需要为词库建一张至少包含中文词汇以及对应的拼音词汇的表。
通讯录搜索,可能会使用一些例如 pinyin4j 的第三方库,将中文字转换为拼音。当然也我们可以自己实现转换拼音的功能,如果这样做,则需要在代码中设定好中文字库和对应的拼音,同时特别注意多音字的处理。

下面是使用 pinyin4j 库的例子。使用 pinyin4j 库可以支持简体 / 繁体中文转换为拼音,而且支持带声调的格式化输出。
我们使用 Maven 来添加 pinyin4j,在 pom.xml 中添加

    <dependencies><dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.0</version></dependency></dependencies>

实现类:

public class Chinese {private HanyuPinyinOutputFormat format = null;private String[] pinyin;public Chinese() {format = new HanyuPinyinOutputFormat();format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);pinyin = null;}//转换单个中文字符public String getCharacterPinYin(char c) {try {pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);} catch(BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}// 如果c不是汉字,返回nullif(null == pinyin)return null;// 多音字取第一个值return pinyin[0];}//转换一个字符串public String getStringPinYin(String str) {StringBuilder sb = new StringBuilder();for(int i = 0; i < str.length(); ++i) {String tmp = getCharacterPinYin(str.charAt(i));if(null == tmp) {// 如果str.charAt(i)不是汉字,则保持原样sb.append(str.charAt(i));} else {sb.append(tmp);//分词if ( i < str.length() - 1 && null != getCharacterPinYin(str.charAt(i + 1))) {sb.append("\'");}}}return sb.toString().trim();}public static void main(String[] args) {Chinese chinese = new Chinese();String str = "哈哈,我爱 Coding";String pinYin = chinese.getStringPinYin(str);System.out.println(pinYin);}
}

输出的结果

ha'ha,wo'ai Coding

每当有通讯录联系人更新时,采用上述方法更新数据库中的拼音字段即可。

站内搜索,词库来源可以使用搜狗标准词库和细胞词库等。
搜狗标准词库

下载的搜狗词库可以使用深蓝词库转换器来转换成 txt 文件,或者其他输入法的标准格式。
深蓝词库转换 2.0

转换为 txt 文件后,处理以后,修改成为 insert 语句,插入数据库。

最后的关键,就是将输入的拼音分词,然后与数据库中的拼音字段匹配,分词采用正则表达式实现。

分词实现:

public class PinyinUtils {//分词正则表达式public static String regEx  = "[^aoeiuv]?h?[iuv]?(ai|ei|ao|ou|er|ang?|eng?|ong|a|o|e|i|u|ng|n)?";public static String split(String input) {int tag = 0;StringBuffer sb = new StringBuffer();String formatted = "";List<String> tokenResult = new ArrayList<String>();for (int i = input.length(); i > 0; i = i - tag) {Pattern pat = Pattern.compile(regEx);Matcher matcher = pat.matcher(input);boolean rs = matcher.find();sb.append(matcher.group());sb.append("\'");tag = matcher.end() - matcher.start();tokenResult.add(input.substring(0, 1));input = input.substring(tag);}if (sb.length() > 0) {formatted = sb.toString().substring(0, sb.toString().length() - 1);}return formatted;}public static void main(String[] args) {String str = "koudingboke";System.out.println(PinyinUtils.split(str));}
}

输出结果

kou'ding'bo'ke

根据此输出结果,在词库中匹配即可。

根据以上方式搜索出的词汇,会比较固定。如果有按照搜索频率对搜索结果排序的需求,可以针对每个词汇的查询计数。具体实现这里不再赘述。

个人一点粗浅经验,欢迎各位大牛一起交流。

参考来源

怎样对拼音进行切分?

Brook Zhao

本文来自 Coding 官方技术博客,如需转载请注明出处,谢谢。

谈谈我做拼音搜索的一点经验相关推荐

  1. 关于asterisk做呼叫转接的一点经验记录

    第一天 上午接到一个需求,询问现在我们的电话系统是否能做个呼叫转接.然后在网上搜了一下,发现有路子可走,所以简单试了一下,还真是可以. 首先,需求是什么? 客户拨通了400电话到我们的asterisk ...

  2. 谈谈8年C++面向对象设计的经验体会

    六年前,我刚热恋"面向对象"(Object-Oriented)时,一口气记住了近十个定义.六年后,我从几十万行程序中滚爬出来准备写点心得体会时,却无法解释什么是"面向对象 ...

  3. 命名实体识别的一点经验与技巧

    最近做了一点微小的工作,搞了下命名实体识别(named entity recongnition, NER),这里总结一下目前的认识.内容比较杂,先亮一下目录,如图0-1. 图0-1 目录 一.什么是命 ...

  4. 命名实体识别的一点经验

    最近做了一点微小的工作,搞了下命名实体识别(named entity recongnition, NER),这里总结一下目前的认识.内容比较杂,先亮一下目录,如图0-1. 标图0-1 目录题 1什么是 ...

  5. 如何找实习单位(个人的一点经验)

    发信人: NetBSD (BSD on amy platform), 信区: Intern 标  题: 如何找实习单位(个人的一点经验) 发信站: 水木社区 (Tue Mar 28 16:03:41  ...

  6. 赚钱副业项目:steam搬砖的一点经验

    进入正文 首先向大家说明一下,玩这个steam游戏道具搬砖项目,不必非得会玩游戏. 到目前操作这个项目2年时间了,那么接下来谈谈自己的一点经验. 关于选品.出售上架的13条核心经验: 建议新手入场的时 ...

  7. 各路高手谈谈手工焊接贴片元件的方法、经验

    2006-05-08 15:28:22 各路高手谈谈手工焊接贴片元件的方法.经验,所用工具 作者[王为之][duoduo][mudfish]© --- 摘自 C51BBS论坛 --- [王为之] 我也 ...

  8. 知乎嵌入式大杂烩:学习STM32的一点经验分享

    前言 前两天在群里看到群友们在讨论学习STM32的话题,并且今天也有一位机械专业的准研究生也问了STM32的入门问题.正好我也有一点经验,所以试着分享一下这个话题.我也不是什么大神,只是一名普通的工程 ...

  9. 【Solr】 solr对拼音搜索和拼音首字母搜索的支持

    问:对于拼音和拼音首字母的支持,当你在搜商品的时候,如果想输入拼音和拼音首字母就给出商品的信息,怎么办呢? 实现方式有2种,但是他们其实是对应的.  用lucene实现 1.建索引, 多建一个索引字段 ...

最新文章

  1. 自带数据线的迷你数显充电宝,旅途必备
  2. 超全的Go Http路由框架性能比较
  3. JavaScript 3D图表
  4. VC++ 中ListCtrl经验总结
  5. PHP算法根据周数获取开始结束日期
  6. 使用CountDownLatch来模拟马拉松比赛
  7. 树莓派 触摸屏_如何用树莓派搭建一个颗粒物(PM2.5)传感器
  8. 云南计算机一级c类基础知识,云南省大学计算机 一级C类 【多选题及答案】
  9. AlexNet,VGG,GoogleNet,ResNet
  10. Bitmap如何高效加载图片
  11. android内存泄漏原因分析,Android 内存泄漏案例分析总结(Handler)
  12. java学习随笔(三)
  13. NLP-文本分类(2)
  14. Keil 5模块化编程详细步骤
  15. 金融用计算机,CFA考试指定计算器使用攻略
  16. R语言从github安装recharts包
  17. 计算机类学术论文格式,学术论文的标准格式是什么
  18. Katana程序集列表
  19. debian设置IP
  20. 中职计算机教师考核工作总结,中职计算机教师教学工作总结

热门文章

  1. 【Windows10下.sh文件的运行】‘bash’ is not recognized as an internal or external command
  2. android的apk加壳工具对比
  3. php使用addons,think addons教程
  4. Python入门如何给自己写一个文字小游戏?一只小白的Python游戏
  5. windows下使用cmd命令文件批量重命名批量修改后缀重命名快捷键
  6. wince buid
  7. Android凉了也要看的面试题,2020年5月美团Android面试真题(三面
  8. uip-学习笔记(移植篇)
  9. cocos2dx在Android studio运行 以及在 Android 平台上使用 JavaScript 直接调用 Java 方法
  10. vs2017开发ActiveX(主讲OCX)(八)、添加常用方法