一.汉字转拼音的现状

首先应该说,汉字转拼音是个强需求,比如联系人按拼音字母排序/筛选;比如目的地(典型如机票购买)

按拼音首字母分类等等。但是这个需求的解决方案,但好像没听过什么巧妙的实现(特别是浏览器端),大概都需要一个庞大的字典。

具体到JavaScript,查查github和npm,比较优秀的处理汉字转拼音的库有pinyin

和pinyinjs,可以看到,两者都自带了庞大的字典。

这些字典动辄几十上百KB(有的甚至几MB),想在浏览器端使用还是需要一些勇气的。所以当我们碰到汉字转拼音的需求,也不怪我们第一反应就是拒绝需求(或者服务端实现)。

现在,如果我告诉你可以浏览器端300行代码实现汉字转拼音,是不是不可置信?

二.从安卓4.2.2联系人代码说起

再次强调这篇博客——利用Android源码,轻松实现汉字转拼音功能。

今天和大家分享一个从Android系统源代码提取出来的汉字转成拼音实现方案,只要一个类,560多行代码就可以让你轻松实现汉字转成拼音的功能,且无需其他任何第三方依赖。

是不是打破了你的思维定势:难道有什么强大的算法可以抛弃字典?

第一遍看完博客,稍有些失望,并没有什么算法解析,只是介绍了从安卓代码发现的这几百行代码。第二遍时带着移植到JavaScript的想法阅读代码,算是弄懂了原理,于是开始了踩坑的移植之旅。

三.手把手教你300行JavaScript代码实现汉字转拼音

首先直指核心:为什么有汉字转拼音必须有庞大字典的思维定势?

因为汉字的排布和拼音并有什么关联,比如在汉字区间\u4E00-\u9FFF,前一个可能是ha,后一个可能就是ze,没有办法从汉字的unicode关联到拼音,所以只能有一个庞大的字典记录每个汉字(或常用汉字)的拼音。

但是,假设我们可以把所有汉字按拼音排序,比如按'A','AI','AN','ANG','AO','BA',...,'ZUI','ZUN','ZUO'排序,那么,我们只需要记住每个相同拼音的汉字队列的第一个汉字就好了。那么,所需要的字典就会很小(覆盖所有拼音即可,拼音数量本身不多)。

现在,难点就是把汉字按拼音排序了。很幸运,ICU/本地化相关的API提供了这个排序API(如果没有方便的排序/比较方法,那么本篇文章可能就不会出现了)。

所以,这就是为什么300行可以实现汉字转拼音:Intl.CollatorAPI:Intl.Collator内部实现了本土化相关的字符串排序。我们通过Intl.Collator.prototype.compare可以把所有汉字基本按照拼音来排序。

边界汉字表:记录了排序的边界点。该汉字表的每个汉字都是排序后相同拼音的汉字集合的首个汉字(Eachunihansisthefirstonewithinsamepinyinwhencollatoriszh_CN)。

说到这里,可能仍然有没说清楚的地方,所以直接上一段代码:

有兴趣的同学可以执行node--icu-data-dir=node_modules/full-icu上面的脚本.js看看,然后看看是不是得到了基本按照拼音排序的汉字表。

这里有几点要注意:

我再次加粗了“基本”,因为我们得到的汉字列表并没有完全按照拼音来排序,中间偶尔有一些其它拼音的汉字插入,这点在制作边界表时要额外注意。

上面脚本里得出的表是所有汉字的排序,其中有些和安卓代码里HanziToPinyin.java的表有不同,所以需要更新HanziToPinyin.java的表。(从Java转到JavaScript的最大的坑和工作量:更正边界表)

相信大家都看到了核心代码:constCOLLATOR=newIntl.Collator(['zh-Hans-CN']),Intl.Collator

(这里指定locale是中国zh-Hans-CN)正是能把汉字按拼音排序的关键,它是按locale-specific顺序,排序字符串的InternationalizationAPI。

执行脚本时请先npmifull-icu,这个依赖会自动安装缺失的中文支持并提示如何指定ICU数据文件来执行脚本。

1.ICUICU即InternationalComponentsforUnicode,为应用提供Unicode和国际化支持。

ICUisamature,widelyusedsetofC/C++andJavalibrariesprovidingUnicodeandGlobalizationsupportforsoftwareapplications.ICUiswidelyportableandgivesapplicationsthesameresultsonallplatformsandbetweenC/C++andJavasoftware.

并且ICU提供了本地化字符串比较服务(UnicodeCollationAlgorithm+本地特定的比较规则):

Collation:Comparestringsaccordingtotheconventionsandstandardsofaparticularlanguage,regionorcountry.ICU'scollationisbasedontheUnicodeCollationAlgorithmpluslocale-specificcomparisonrulesfromtheCommonLocaleDataRepository,acomprehensivesourceforthistypeofdata.

在现代浏览器上,一般ICU内置了对用户本地语言的支持,我们直接使用即可。

但对node.js来说,通常情况下,ICU只包含了一个子集(通常是英语),所以我们需要自行添加对中文的支持。一般来说,可以通过npminstallfull-icu安装full-icu

来安装缺失的中文支持。(参见上面node--icu-data-dir=node_modules/full-icu)。

2.IntlAPI上一小节应该基本讲清楚了国际化/本地化相关的知识,这里再补充一下内置API的使用。怎么查看用户语言和Runtime是否支持这个语言?Intl.Collator.supportedLocalesOf(array|string)

返回包含支持(不用回退到默认locale)的locales的数组,参数可以是数组或字符串,为想要测试的locales(即BCP47languagetag)。

构造Collator对象和排序字符串

通过Intl.Collator.prototype.compare,我们可以按语言指定的顺序来排序字符串。而中文中,这个排序恰好绝大多数都是按拼音的顺序来的,'A','AI','AN','ANG','AO','BA','BAI','BAN','BANG','BAO','BEI','BEN','BENG','BI','BIAN','BIAO','BIE','BIN','BING','BO','BU','CA','CAI','CAN',...

,这正是我们上面提到的汉字转拼音的关键。

四.边界表更正

显然,这个边界表是有问题的,需要更正。

我们可看到,大部分的汉字被转成了qing,可见,qing这个拼音对应的汉字有问题。

找到这个汉字,是'\u72c5'/'狅',加上前后各一个字,['\u4eb2','\u72c5','\u828e']/["亲","狅","芎"]

搜索,'\u72c5'/'狅'可以读qing,但现在多读kuang,这应该就是错误的原因了。

根据最初得到那张所有汉字的排序表,qing的第一个汉字是'\u9751'/'靑'。

改动后,转换失败的只剩104了。

java300行程序代码_神级程序员JavaScript300行代码搞定汉字转拼音相关推荐

  1. 知道经纬度用python画路线图_神级程序员教你用Python如何画一个中国地图!(好好玩)...

    为什么是Python 先来聊聊为什么做数据分析一定要用 Python 或 R 语言.编程语言这么多种, Java , PHP 都很成熟,但是为什么在最近热火的数据分析领域,很多人选择用 Python ...

  2. python中国地图程序设计_神级程序员教你用Python如何画一个中国地图!(好好玩)...

    为什么是Python 先来聊聊为什么做数据分析一定要用 Python 或 R 语言.编程语言这么多种, Java , PHP 都很成熟,但是为什么在最近热火的数据分析领域,很多人选择用 Python ...

  3. python交流企鹅裙_神级程序员巧用python开发王者荣耀把妹神器,一路升级上王者!...

    Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...

  4. python发邮件怎么用服务器每天发_神级程序员的Python爬虫!服务器定时发邮件(知识点全面)...

    很多小伙伴找我问:老铁,这些代码我写的和你一样,为什么我的不行.其实这是最基本的函数,你照葫芦画瓢是没什么多大的作用的.我不会直接告诉你答案也不是我不想告诉你,而是希望你能跟着思路,自己找到答案,这才 ...

  5. python项目了解_神级程序员都是这样来开源 Python 项目!今天算是涨知识了!

    工具和概念 项目布局 当准备一个项目时,正确合理的布局(目录结构)是十分重要的.一个合理的布局意味着想参与开发者不必花时间来寻找某些代码的位置; 凭直觉就可以找到文件的位置.因为我们在处理一个项目,就 ...

  6. 有趣的超短python代码_神级Coder绝不犯的错误:为炫耀编出超短码

    注:原文作者为 Allan Reyes 一名退伍军人兼工程师.本文以第一人称编译. 我常逛像是 Exercism 等网站,我在那里编写或重温一些习题来提升我的编码技巧.但现在有个危险的流行正在蔓延,我 ...

  7. 有趣的超短python代码_神级 Coder 绝不犯的错误:为炫耀编出超短码

    本篇原文来自<Medium>,原文作者为 Allan Reyes 一名退伍军人兼工程师.本文以第一人称编译. 我常逛像是 Exercism等网站,我在那里编写或重温一些习题来精进我的编码技 ...

  8. 《千字文细谈》2021神级程序员都在用什么工具?-09-02

    答者:如下图  普通码农一枚,分享一下自己最常使用的几个效率生产工具. 目前还没看到神级程序员的回答,问题先码一下,坐等神级程序员. 下面本人抛砖引玉的回答: 1.关于架构设计和系统设计:会推荐几个自 ...

  9. 怎么用python制作简单的程序-神级程序员教你如何用python制作一个牛逼的外挂!...

    玩过电脑游戏的同学对于外挂肯定不陌生,但是你在用外挂的时候有没有想过如何做一个外挂呢?(当然用外挂不是那么道义哈,呵呵),那我们就来看一下如何用python来制作一个外挂.... 我打开了4399小游 ...

最新文章

  1. SQL Server误区30日谈-Day27-使用BACKUP ... WITH CHECKSUM可以替代DBCC CheckDB
  2. java性能调优及问题追踪--Btrace的使用
  3. Ubuntu安装配置Python.pyDev
  4. c++数据结构队列栈尸体_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)...
  5. flex gallery / 产品展示
  6. nginx stream模块
  7. Keras-6 IMDB, a binary classification example
  8. KMP算法的一个C++实现
  9. Graph-Bert:没有我Attention解决不了的
  10. 推荐一款串口调试助手(win10,无广告,功能齐全,操作简单)
  11. 网安学习——信息收集
  12. FinClip手把手教学:如何从零开始编写一个app
  13. linux c 拒绝服务攻击,低速率拒绝服务攻击原理
  14. Matplotlib——条形图_3、分组条形图_4、堆叠条形图
  15. 【Python】使用日历热图进行时序数据可视化
  16. h5py使用基础笔记
  17. 19 - Dva框架基础
  18. 计算机技术应用于教学案例,信息技术应用教学案例.doc
  19. Lit(二):响应式属性
  20. 撕掉代工标签,能否迎来芯片市场的“权力转移”?...

热门文章

  1. html5排版的价格表,分享各种报价表单页面设计的网站:Pricing Pages
  2. TSP库中各规模数据的已知最优解大小
  3. 基于准则的结构化决策指南_如何记录团队技术决策的指南
  4. 一个故事讲清https
  5. Qt 使用笔记 --转自 wangwenx190/Note
  6. 传微软最快将于8月1日向合作伙伴分发Win8 RTM
  7. 综合管廊智慧运维管理平台应用研究
  8. 霍金是不是“自爱因斯坦以来最伟大的理论物理学家”?
  9. matlab中表示拉普拉斯分布_matlab 拉普拉斯变换
  10. 华为交换机端口限速配置