本文主要介绍JPinYin的使用和配置,github的地址。
简单介绍
Jpinyin是一个开源的用于将汉字转换为拼音的java库。
主要特性
1、准确、完善的字库:Unicode编码从4E00-9FA5范围及3007(〇)的20903个汉字中,除了46个异体字(不存在标准拼音)Jpinyin都能转换。
2、拼音转换速度快:经测试,转换Unicode编码范围的20902个汉字,Jpinyin耗时约为100毫秒。
3、支持多种拼音格式:Jpinyin支持多种拼音输出格式:带声调、不带声调、数字表示声调以及拼音首字母格式输出。
4、常见多音字识别:Jpinyin支持常见多音字的识别,其中包括词组、成语、地名等;
5、简繁体中文互转。
6、支持用户自定义字典。
Maven依赖
|
|
用法
|
|
源码分析
下面的部分,试着从源码来理解Jpinyin,以便更好的使用它。
结构
根据(图-1)中可以看出,Jpinyin的实现主要由6个Java类来实现,其中PinyinException是一个异常类,定义了Pinyin异常;PinyinFormat为枚举类,用于定义汉字转拼音的格式(前面提到的:带声调、不带声调和数字表示声调三种),主要作为PinyinHelper类中方法的参数;PinyinHelper类,用来将汉字转换为不同格式的拼音,以及将汉字转换为拼音首字母缩写;PinyinResource类,用来加载拼音资源,主要是提供了从文件加载字典数据,并将数据以字典(Map)类型的数据结构保存在内存中;ChinesHelper类,用来是实现汉字繁简互转的功能;DoubleArrayTrie类,是Double-Array trie的实现,用来将词组装配成一棵,并使用这棵树来检测词组。
根据(图-2)中可以看出,Jpinyin的资源中有三个数据文件,分别为chinese.dict、mutil_pinyin.dict和pinyin.dict。其中,chinese.dict存储的是繁体字与简体字之间的对应关系;mutil_pinyin.dict存储的是词组;pinyin.dict存储的是单字的读音(如果是多音字则对一个多个拼音,多个拼音之间使用逗号分隔,如:重=zhòng,chóng)。
代码
了解了项目工程的结构,我们来具体的看一下Jpinyin的实现
PinyinException类
|
|
该类主要就是定义了一个异常类,用于区分普通异常和该项目的异常。
pinyinFormat类
|
|
该类为枚举类型,用来定义拼音的格式。主要作为PyinHelper类中方法的参数,用来在汉字转换为拼音时的格式,如:
其中WITH_TONE_MARK表示带声调的拼音格式,如nǐ,hǎo,shì,jiè;WITHOUT_TONE表示不带声调的拼音格式,如ni,hao,shi,jie;WITH_TONE_NUMBER表示使用数字表示声调的拼音格式,如ni3,hao3,shi4,jie4。
PinyinResource类
PinyinResource类主要用来加载资源文件(resource/data目录中的数据文件),并将资源文件以Map为数据结构保存到内存中。该类提供了6个方法:
两个方法用于获取资源的输入,并以UTF-8格式读入:
一个资源加载方法,并以Map作为数据结构进行存储:
三个资源加载调用方法,分别加载pinyin.dict、mutil_pinyin.dict、chinese.dict:
ChineseHelper类
ChineseHelper类主要用于繁体字和简体字之间的转换、体字的检测,并提供了一个方法用来扩展用户自定义的繁体字对应简体字的字库(字库的格式必须是key=value,因为它使用的是PinyinResource中的资源加载方式)。
首先是两个类变量:
简体字和繁体字之间的互转,包括单个字和多个字:
字体检测:
添加用户自定义的繁体字对应简体字的字库:
PinyinHelper类
PinyinHelper类主要用于将中文的汉字转换为拼音(支持三种格式),并提供了添加用户自定义的汉字与拼音关系(单字和词组)的资源库的功能。
首先是类变量:
静态块:
将声调格式的拼音转换为以数字表示声调的拼音
将带声调的拼音转换为不带声调的拼音,并以数组的形式返回,每个数组项是一个字的拼音
将拼音字符串按照给定的格式进行格式化,并以数组的形式返回,需要注意的是,这个方法只是提供格式化,提供的字符串已经是拼音了
将单个汉字以pinyinFormat指定的格式进行转换,以数组的方式返回,是为了兼容多音字,多音字会返回多个拼音
将字转换为带有声调的拼音,通过调用convertToPinyinArray
将字符串转换为指定格式的拼音字符串,并且品字符串中各个字的拼音之间使用separator指定的分隔符分隔
将汉字字符串转换为带声调格式的拼音,调用convertToPinyinString方法,并指定转换的格式
判断一个汉字是否是多音字,其实现就是将单个汉字转换为拼音数组,并判断返回的数组的元素的个数
将汉字字符串转换拼音首字母
添加用户自定义汉字与拼音的对应关系数据,要求添加的文件的格式必须是key=value,其中key是汉字,value是拼音。因为使用的统一的资源加载器。
添加用户自定义的词组与拼音的对应关系数据,要求数据文件的格式必须是key=value,其中key是词组,value是对应的拼音。因为它使用的是统一的资源加载器。
DoubleArrayTrie类
DoubleArrayTrie类是一个前缀树的实现,主要用来查找词组或短语:
累的定义如下,首先是类变量和类的私有类:
重新分配Double-Array trie内部核心数组check和base的方法,根据指定的大小生成新的数组,并将原来数组的数据完整的拷贝的新数组中:
根据父节点提取子节点数据的方法,并返回子节点的个数,所有子节点的数据通过参数siblings进行返回:
Double-Array trie的构建方法,通过上面的fetch获取子节点,然后利用本方法来构建两个数组的数据:
Double-Array trie类的默认构造方法:
计算数组存储的基本单元的大小:
计算Double-Array tire的有效大小,和分配的大小不同:
计算Double-Array trie所占用的有效空间:
计算Double-Array trie中核心数组check和base中真正存储了数据的数据单元个数:
构建Double-Array trie的方法,key是一个挣序排序后的集合,集合中包含了所需的所有数据:
构建Double-Array tire的方法,本方法为实际操作方法,并且提供了更加丰富的参数:
从文件中加载已有的Double-Array trie的数据,并重新构建成可用的Double-Array trie:
将现有的Double-Array trie保存到文件:
在Double-Array trie中精确匹配搜索给定的词组:
在Double-Array trie中精确匹配搜索,该方法为实际搜索方法:
该方法主要用来精确匹配搜索的,理解该方法也是理解inster方法的关键,接下来我们将详细介绍并举例该方法。
……
常用前缀搜索方法:
常用前缀搜索方法的具体实现:
理解该方法也是理解前缀搜索的关键,更加有助于理解insert方法的实现。……
调试方法,会将Double-Array trie的关键数组check和base打印出来:
总结
通过源码分析,Jpinyin可以方便的将汉字转换为拼音,也可以方便的将繁体字转换为简体字,但是不足之处是,在将简体字转换为繁体子的时候,效率会非常的低。另外,对于特殊的46个异体字,没有明确的指出,从而加以区分。
单单从汉字转拼音的角度来说,该功能比较好用,但是如果考虑到自然语言处理的应用,还是有很多不足的地方。例如,表情符号也可以代表汉字,也就对应着拼音;unicode其实也是汉字的另一种表示,也应该有对应的拼音;等等。
其他备注
moji表情一般是两个unicode,但也有一部分是一个unicode
String pattern = “[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]”
moji表情与unicode的对应
moji表情和unicode字符串之间的相互转换可以使用apache的commons-lang包中StringEscapeUtils类的escapeJava(String)和unescapeJava(String)来进行相互转换。