项目中遇到一个姓名带出中文拼音的需求,于是整理了一下实现方法。
注意一下:在转换中,这里我保留了数字、字母、空格,而且空格转为了
-
,一些特殊字符的去掉了。如哈,哈 o噢
=>HaHa-oAo
。如果想要定制修改的话,自行修改convertToPinyin()
的里面的方法就好。
话不多说,往下看,文章最后对多音字
和生僻字
的看法。(附上 PinYin.js 下载链接)
// html
<input id="input1" value="测试" />
<input id="output1" disabled />
// 引入一个 16 进制 Unicode 编码的 JS 文件
// Pinyin.js 链接在文章顶部,自行下载到本地之后,以下路径对应修改
// 这个是本人网上收集整理的,已可自行下载补充一些缺失的中文字符
// JS 文件中有说明补充一些缺失字符的方法
<script type="text/javascript" src="./Pinyin.js"></script>
// js
let input = document.getElementById('input1');
let output1 = document.getElementById('output1');
input.addEventListener('blur', () => {
let val = input.value;
output1.value = convertToPinyin(val);
})
/**
*
* @param {*} sourceData 原始数据
* @returns targetData 返回大写中文拼音
*/
function convertToPinyin(sourceData) {
// 源数据
let sourceDataLen = sourceData.length;
// 目标数据
let targetData = '';
// 匹配中文
let chineseReg = new RegExp('[\u4e00-\u9fa5]');
// 匹配数字和英文
let enReg = new RegExp('[a-zA-Z0-9 ]');
// 保留英文和数字,否则为false
let keep = true;
// 遍历源数据
for (let i = 0; i < sourceDataLen; i++) {
let str = sourceData.substr(i, 1);
if (keep && enReg.test(str)) {
targetData += str;
} else if (chineseReg.test(str)) {
let searchResult = this.searchPinYin(str, PinYin);
// searchResult !== false && (targetData += searchResult);
// 首字母大写
searchResult !== false && (targetData += this.firstCapital(searchResult));
}
}
// 空格 转 -
targetData = targetData.replace(/ /g, '-')
return targetData;
}
// 检索拼音
function searchPinYin(str, obj) {
for (let name in obj) {
if (obj[name].indexOf(str) != -1) {
return name;
}
}
return false;
}
// 首字母大写
function firstCapital(str) {
if (str.length > 0) {
let first = str.substr(0, 1).toUpperCase();
let spare = str.substr(1, str.length);
return first + spare;
}
return str;
}
其实在中文转拼音的过程中,比较麻烦的在于多音字
和生僻字
的实现,我想到的解决思路是:
-
生僻字:是由于 PinYin.js 里缺失一些中文字符,可通过
String.charCodeAt(0).toString(16)
的方式补充,具体方法不叙述了,上面文件里有说明。 -
多音字:其实多音字一直是最麻烦的地方,因为每一个中文字符只有一个对应的Unicode编码,所以需要在对象的多个对应属性上添加编码。
如曾
字,通过'曾'.charCodeAt(0).toString(16)
获取到66fe
,然后前面拼接上\u
,得到\u66fe
。
// 截取 PinYin.js 一小部分
const PinYin = {
"ceng": "\u66fe",
"zeng": "\u66fe",
}
然后修改上述 convertToPinyin()
和 searchPinYin()
方法,把符合规则的字符返回一个数组,然后用排列组合
的方式列出所有可能。
如果各位大神有更好的实现方法,请留下,谢谢!
网友评论