1.汉字拼音化的现状
首先应该说,汉字到拼音的转换是一个很强的需求,比如通过拼音字母对联系人进行排序/过滤;比如目的地(如机票购买)按拼音首字母等分类。然而,这个需求的解决方案似乎从未听说过任何巧妙的实现(尤其是在浏览器端),这可能需要一个巨大的字典。具体到JavaScript,查一下github和npm。将汉字处理成拼音的优秀库有拼音库和拼音库。我们可以看到,他们都有自己的大型词典。这些字典通常是几十千字节(有些甚至是几兆字节),所以在浏览器端使用它们需要一些勇气。因此,当我们满足了将汉字转换为拼音的需求时,我们的第一反应就是拒绝需求(或者在服务器端实现)也就不足为奇了。现在,如果我告诉你,你可以在浏览器上用300行代码把汉字转换成拼音,是不是不可思议?
2.从安卓4.2.2联系代码开始
再次强调一下,这个博客——可以使用安卓源代码轻松实现汉字转换为拼音的功能。今天给大家分享一个从安卓系统源代码中提取的汉字转换为拼音的实现方案。只需一个类,560多行代码,就可以轻松实现将汉字转换为拼音的功能,无需任何其他第三方的依赖。是否打破了你的思维定势:有没有什么强大的算法可以抛弃字典?第一次看博客,有点失望。我没有任何算法分析。我刚刚介绍了从安卓代码中找到的数百行代码。第二次,带着移植到JavaScript的想法读代码,明白了原理,就开始了踩坑的迁移之旅。
3.教你300行JavaScript代码,实现汉字到拼音的转换
首先开门见山:为什么你会有把汉字转换成拼音需要庞大字典的心态?因为汉字的布局和拼音没有关系,比如在汉字区间 u4e 00- u9ff,前者可能是ha,后者可能是ze,所以没有办法把汉字的unicode和拼音联系起来,所以只能有一个巨大的字典来记录每个汉字(或者常用汉字)的拼音。但是,如果我们能把所有汉字按拼音排序,比如‘a’、‘ai’、‘an’、‘ang’、‘ao’、‘ba’,‘zui’,‘Zun’,‘zoo’,那么我们只需要记住每个汉字队列中第一个拼音相同的汉字。那么,所需的词典就会很少(涵盖所有拼音,拼音本身的数量并不多)。现在的难点是汉字按拼音排序。好在ICU/本地化相关的API提供了这个排序API(如果没有方便的排序/比较方法,这篇文章可能不会出现)。
所以,这就是为什么300行就可以把汉字转换成拼音:intl。整理器API:国际。排序器在内部实现与本地化相关的字符串排序。我们可以通过intl按照拼音对所有汉字进行排序。排序器.原型.比较.边界汉字表:记录排序后的边界点。汉字表中的每一个汉字都是经过排序后的第一个拼音相同的汉字集(eachunihanshehsfirst one withinsaphiinwhencollectorszh _ cn)。话虽如此,可能还是有一些不清楚的地方,直接进入前面的代码:
感兴趣的学生可以执行脚本。上面的js node-ICU-data-dir=node _ modules/full-ICU看看他们有没有拿到基本按拼音排序的汉字列表。
这里有几点需要注意:
我再一次把“基本”加粗了,因为我们拿到的汉字列表并没有完全按照拼音排序,中间偶尔会插入一些带有其他拼音的汉字,在做边界列表的时候要格外注意。上面脚本中的表是全汉字的排序,有些和安卓代码中HanziToPinyin.java的表不一样,需要更新HanziToPinyin.java的表。(从Java转移到JavaScript最大的坑和工作量:修正边界表)相信大家都看过核心代码:const collator=new Intl。Collator (['zh-Hans-CN']),intl.collator(在中国,区域设置被指定为zh-Hans-CN)是按拼音对汉字进行排序的关键,拼音是特定于区域设置的。执行脚本时请使用npmifull-icu。这种依赖会自动安装缺失的中文支持,并提示如何指定ICU数据文件来执行脚本。1.ICU是unicode的国际组件,为应用程序提供Unicode和国际化支持。icuisa成熟、广泛使用的set fc/C和javalibrariesprovingnicodedglobalizationsupportfor软件应用程序。iciswaidelyportableandgivesapplicationsamesresultsonallplatformsan数据库中间件/C和Javasoftware。而ICU提供本地化字符串比较服务(UnicodeCollationAlgorithm本地特定比较规则):collation:根据check事件和standardsofapartcul arlanguage,regionorcountry进行比较。重症监护室的代码是一个数据库,包含了非特定规模的比较规则。在现代浏览器中,ICU内置了对用户本地语言的支持,所以我们可以直接使用。但是对于node.js来说,ICU通常只包含一个子集(通常是英文),所以需要我们自己添加对中文的支持。一般来说,你可以通过npminstallfull-icu安装full-icu来安装缺失的中文支持。(见上面node-ICU-data-dir=node _ modules/full-ICU)。2.第二部分的最后一节。IntlAPI应该基本明确了国际化/本地化相关的知识,这里我们将补充内置API的使用。如何检查用户语言和Runtime是否支持这种语言?int l . collator . supported locale of(array | string)返回一个包含支持的区域设置的数组(不回退到默认区域设置)。参数可以是数组或字符串,这是要测试的语言环境(即BCP47languagetag)。
构造排序器对象和排序字符串
使用intl . collator . prototype.compare,我们可以按照语言指定的顺序对字符串进行排序。在汉语中,这种排序恰好大部分是按拼音顺序排列的,“一”、“艾”、“安”、“昂”、“奥”、“巴”、“白”、“班”、“榜”、“保”、“备”、“本”、“蚌”
四.边界表的修正
显然,这个边界表是有问题的,需要纠正。我们可以看到大部分汉字都已经转换成了清,这说明对应清的汉字有问题。我找到了这个汉字,是“u72c5”/“ying”,前后加一个字,[“ u4eb 2”、“ u72c 5”、“ u 828 e”]/[“pro”、“ying”、“Xiong”]。搜索,' u72c5'/' 8 '可以读清,但现在读旷比较多,这应该是错误的原因。根据所有汉字的初始列表,清的第一个汉字是“ u 9751”/“镝”。更改后,只有104个转换失败。