通讯录文件格式(写通讯录表的格式)

导航

  • 微信通讯录
  • 尝试利用pinyin4j实现
  • 尝试利用JPinyin实现
  • 尝试利用pinyin4j-multi实现
  • 结语
  • 参考

本文摘自是智客工坊系列文章,感谢您的阅读,预计阅读时长3min。


通讯录文件格式(写通讯录表的格式)


微信通讯录

说道IM,微信是绕不开的话题,毕竟在这个领域微信就是事实上的标杆。

最近,产品经理给我们提了一个功能,内部IM系统增加一个通讯录功能。

规则如下:

  • 根据通讯录好友昵称的首字母(或首个汉字拼音首字母)由A-Z排序
  • 部分好友昵称是数字或表情符号(比如爱心、气球等等),将会归到#类中
  • # 排在 A~Z分类之后

咋一看挺简单,毕竟这样的功能大伙儿都很使用过,但是一落实很真不是那么容易。

因为是参照微信的设计,需要对联系人按照首字母排序。而这里的症结是如何准确提取出联系人名字中的拼音首字母。

尝试利用pinyin4j实现

根据规则,我们已经知道,只要能够提取出联系人的拼音首字母,工作就完成一大半了。

项目是基于Springboot框架的,于是很确定的打开google搜索了一把看有没有这样的插件,手气不错,推荐了使用pinyin4j。

pinyin4j支持将汉字转换成拼音,使用也很简单。

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

只需要引入这个依赖,就可以直接使用,非常简单。

简单封装了下一下PinYin4jUtils.java


/**
 * Copyright (C) 2022  智客工坊(52interview.com)
 * The SpringBoot Super-blog Project.
 * All rights reserved.
 * <p>
 * > Github地址: https://github.com/zhikecore/superblog.git
 * > 教程地址: https://www.52interview.com/book/36
 * > 智客工坊社区:https://www.52interview.com/
 * <p>
 * 智客工坊(52interview.com) - 经验创造价值,分享成就未来。
 * <p>
 * PinYin4jUtils at 2022/3/12 22:22,code by JeffreyHu
 * You can contact author with zhikecore@foxmail.com.
 */
public class PinYin4jUtils {
     /**
     * 获取汉字串拼音首字母(第一个字母的首字母),英文字符不变
     **/
    public static String getFirstSpell(String chinese) {
        try {
            StringBuffer pybf = new StringBuffer();
            char[] arr = chinese.toCharArray();
            HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
            defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
            defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
            if (arr.length > 0) {
                String[] temp = PinyinHelper.toHanyuPinyinStringArray(arr[0], defaultFormat);
                if (temp != null) {
                    pybf.append(temp[0].charAt(0));
                }
            }
            return pybf.toString().replaceAll("\\W", "").trim();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

写了个简单测试,


 @Test
    void TestGetHeadChar()
    {
    String s1="易烊千玺";
		String firstSpellOfS1= PinYin4jUtils.getFirstSpell(s1);
		System.out.println(firstSpellOfS1.toUpperCase());
    }

查看结果:


通讯录文件格式(写通讯录表的格式)


看起来一切正常,简单封装一下,功能基本完成。

第二天,对接的前端同学说发现了Bug。我表示一脸懵。

经过仔细排查,原来是遇到了多音字问题。

    @Test
    void TestGetHeadChar()
    {
        String s1="乐毅";
		String firstSpellOfS1= PinYin4jUtils.getFirstSpell(s1);
		System.out.println(firstSpellOfS1.toUpperCase());//b
    }

查看结果:


通讯录文件格式(写通讯录表的格式)


这里,"乐毅"的乐是多音字,在姓氏中应该是"yue",而被识别成"le"。

仔细一想,这插件应该没有那么智能。

由于以前使用过分词插件,猜测pinyin4j应该是有扩展词库吧!

查阅相关资料,发现了这个,

外挂多音词库

用户配置的外挂词库会覆盖系统中相同词的读音,可用于纠错

配置方式很简单,只需要配置路径即可

MultiPinyinConfig.multiPinyinPath="/Users/yiboliu/my_multi_pinyin.txt"

于是,赶紧对代码进行了改造。首先,是在resource目录下增加了/py4j/my_multi_pinyin.txt字典。

然后,在PinYin4jUtils中做了一个扩展词库,


String filePath= "/E:/JavaProjects/superblog/blog-webapp/target/test-classes/py4j/my_multi_pinyin.txt";
MultiPinyinConfig.multiPinyinPath = filePath;

再次,测试"乐毅",依然被识别为"le"。反复尝试,无果。

此路不通,只好放弃该方案。

尝试利用JPinyin实现

本着解决问题的目标,心有不甘,又开始寻找方案。这次,有找到了一个神奇JPinyin。

Pinyin是一个汉字转拼音的Java开源类库,在PinYin4j的功能基础上做了一些改进。

JPinyin主要特性

  • 准确、完善的字库;
    Unicode编码从4E00-9FA5范围及3007(〇)的20903个汉字中,JPinyin能转换除46个异体字(异体字不存在标准拼音)之外的所有汉字;
  • 拼音转换速度快;
    经测试,转换Unicode编码从4E00-9FA5范围的20902个汉字,JPinyin耗时约100毫秒。
  • 多拼音格式输出支持;
    JPinyin支持多种拼音输出格式:带音标、不带音标、数字表示音标以及拼音首字母输出格式;
  • 常见多音字识别;
    JPinyin支持常见多音字的识别,其中包括词组、成语、地名等;
  • 简繁体中文转换

这么好的东西,正中下怀。

在代码中赶紧引入,

<!-- 导入jpinyin -->
<dependency>
<groupId>com.github.stuxuhai</groupId>
<artifactId>jpinyin</artifactId>
<version>1.1.7</version>
</dependency>

写了个测试用例:

@Test
void TestGetHeadChar()
{
  try
		{
			String s2="乐毅";

			String r3= PinyinHelper.getShortPinyin(s2);
			System.out.println(r3);
		} catch (PinyinException e) {
			e.printStackTrace();
		}
}


通讯录文件格式(写通讯录表的格式)


从结果来看,非常稳。

jpinyin确实强大,值得收入囊中。但是,有了前车之鉴,我们不得不保持谨慎。

jpinyin似乎并不支持词库扩展,要是遇到生僻词又该如何是好?

为了确保万无一失,再次开启寻找方案之旅。

尝试利用pinyin4j-multi实现

兜兜转转,还是在pinyin4j附近徘徊。这次,事情有了转机。

pinyin4j-multi是基于pinyin4j的多音字解决方案,并支持词库扩展。

"踏破铁鞋无觅处得来全不费工夫"。我想要的东西终于找到了。

在pinyin4j的基础上添加了多音字识别,带近一万个多音词,但是这远远不够,所以用户可设置外挂词库

在项目中引入pinyin4j插件,


<!--导入pinyin4j-multi-->
<dependency>
	<groupId>com.github.obiteaaron</groupId>
  <artifactId>pinyin4j-multi</artifactId>
	<version>1.0.0</version>
</dependency>

为了验证多音字的支持,我特意找了一个专业词汇——"空调"。

@Test
    void TestGetHeadChar() throws Exception {
        String s1="空调";
        String  r1=PinyinHelper.toHanYuPinyinString(s1, outputFormat,";", true);
        System.out.println(r1);
    }

直接使用,识别结果如下:


通讯录文件格式(写通讯录表的格式)


很显然,插件成功的步入了下的套。识别错误。

加上外部词库试试,增加空调 (kong1,tiao2)入库,


吸血鬼日记 (xi1,xue4,gui3,ri4,ji4)
重庆 (chong2,qing4)
朝阳站 (chao2,yang2,zhan4)
吴圩机场 (wu2,xu1,ji1,chang3)
长白山 (chang2,bai2,shan1)
空调 (kong1,tiao2)

测试用例,稍加改造:


 @Test
    void TestGetHeadChar() throws Exception {
        String filePath= this.getClass().getResource("/py4j/my_multi_pinyin.txt").getPath();
        MultiPinyinConfig.multiPinyinPath = filePath;
        String s1="空调";
        String  r1=PinyinHelper.toHanYuPinyinString(s1, outputFormat,";", true);
        System.out.println(r1);
    }

启动调试,结果如下:


通讯录文件格式(写通讯录表的格式)


结果令人满意。暂时就这样吧,真是折腾~

结语

写程序有时候就是这样,充满不确定性。你不得不想做实验一样,一遍一遍地去试错,最后找到一个相对靠谱的解决方案。

通讯录,如此常见的功能,里面也会有不少的潜在逻辑。感谢您的阅读,希望能对您有所帮助~

参考

  • https://github.com/obiteaaron/pinyin4j-multi
  • https://github.com/belerweb/pinyin4j
  • https://www.oschina.net/p/jpinyin

点击播放下方视频,获取100个网络创业项目,

打造每月被动收入8000的副业项目。

添加微信:80709525  备注:创业项目学习群(请一定填写备注,不备注不通过)我拉你进直播课程学习群,每周135晚上都是有实战干货的创业项目推广技术课程免费分享!

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 sumchina520@foxmail.com 举报,一经查实,本站将立刻删除。
如若转载,请注明出处:https://www.vsaren.com/5309.html