JS 中文转换拼音的实现
需求
此前项目中有一个中文转拼音的需求,于是整理了一下实现方法。
在转换过程中,这里我保留了数字和字母,其他特殊字符或者空格将会被去掉。如 测试
会被转换成 CeShi
。(可自行修改 convert2Pinyin()
方法实现其他需求)
实现
话不多说(Github Demo)
<!-- html --> <input value="测试" /> <input disabled />
// js window.onload = () => { const input = document.getElementById('input') const output = document.getElementById('output') // 失焦进行转换 input.addEventListener('blur', () => { const val = input.value output.value = convertToPinyin(val) }) /** * 转换成拼音(若有空格、特殊字符将被移除) * * @param {string} sourceStr 原始数据 */ const convertToPinyin = sourceStr => { // 目标数据 let targetStr = '' // 匹配中文 const cnReg = /[\u4e00-\u9fa5]/ // 匹配数字和英文 const enReg = /[a-zA-Z0-9]/ // 保留英文和数字 const keep = true // 遍历源数据 for (let i = 0, len = sourceStr.length; i < len; i++) { const str = sourceStr.substr(i, 1) if (keep && enReg.test(str)) { targetStr += str } else if (cnReg.test(str)) { const searchResult = searchPinYin(str, PinYin) if (searchResult) { // targetStr += searchResult targetStr += capitalize(searchResult) // 首字母大写 } } } return targetStr } /** * 检索拼音 * * @param {string} str 源字符串 * @param {object} data 收集的拼音 Unicode 编码集合 */ const searchPinYin = (str, data) => { for (const key in data) { if (data.hasOwnProperty(key) && data[key].indexOf(str) !== -1) { return key } } return '' } /** * 将拼音首字母转换为大写 * * @param {string} str 源字符串 */ const capitalize = str => { if (str) { const [first] = str const other = str.replace(/^\S/, '') return `${first.toUpperCase()}${other}` } return str } /** * 目前这个 16 进制 Unicode 编码是网上收集的,可能不能覆盖所有的中文字符,可以自行补充; * * 例如:‘婋’(xiao)字: * 1、使用 '婋'.charCodeAt(0).toString(16) 得到 Unicode 编码:5a4b; * 2、将编码前面加上:\u => \u5a4b; * 3、然后放到对象 PinYin['xiao'] 里面。 * * 现在只想到了这种笨方法一个一个往里补充,如果有更好的方法,欢迎指出!!! */ const PinYin = { a: '\u554a\u963f\u9515' // ... // 由于这块代码太多,这里省略就不贴上来了,麻烦请看 GitHub Demo。 } }
难点
其实在中文转拼音的过程中,比较麻烦的在于 多音字
和 生僻字
的实现,我想到的解决思路是:
- 生僻字:是由于
PinYin
里面列举的缺失一些中文字符,可通过str.charCodeAt(0).toString(16)
的方式补充,具体方法不再赘述,上面有说明。 - 多音字:其实多音字一直是最麻烦的地方,因为每一个中文字符只有一个对应的 Unicode 编码,所以需要在对象的多个对应属性上添加编码。
如曾
字,通过'曾'.charCodeAt(0).toString(16)
获取到66fe
,然后前面拼接上\u
,得到\u66fe
。
// 截取 PinYin 一小部分
const PinYin = {
ceng: '\u66fe',
zeng: '\u66fe'
}
然后修改上述 convert2Pinyin()
和 searchPinYin()
方法,把符合规则的字符返回一个数组,然后用排列组合的方式列出所有可能。
GitHub
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论