欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

将中文姓名转为拼音英文名的一种实现

程序员文章站 2022-07-02 20:23:11
...

需要将中文名转为英文名,这里需要考虑到姓氏以及名字多音字选择,这里记录一下我实现的一种思路。


以下代码均使用JS来进行说明。


处理流程

首先需要判断名字长度以及名字规范

//中文名格式验证
verifyName: function(str) {
	let re = /[^\u4e00-\u9fa5]/;
	const isChinese = str => !re.test(str);
	if (!isChinese(str) || str.length < 2) {
		return false;
	}
	return true;
},

当名字长度超过两个子的时候需要判断复姓的情况,如名字为欧阳日天,那么需要询问用户姓氏为欧阳还是欧,这里只能通过提前预备所有的复姓列表进行检测。

这里提供一份我自己整理的复姓列表:

const doubleFamilyName = [
	'万俟',
	'司马',
	'上官',
	'欧阳',
	'夏侯',
	'诸葛',
	'闻人',
	'东方',
	'赫连',
	'皇甫',
	'尉迟',
	'公羊',
	'澹台',
	'公冶',
	'宗政',
	'濮阳',
	'淳于',
	'单于',
	'太叔',
	'申屠',
	'公孙',
	'仲孙',
	'轩辕',
	'令狐',
	'钟离',
	'宇文',
	'长孙',
	'慕容',
	'鲜于',
	'闾丘',
	'司徒',
	'司空',
	'亓官',
	'司寇',
	'子车',
	'颛孙',
	'端木',
	'巫马',
	'公西',
	'漆雕',
	'乐正',
	'壤驷',
	'公良',
	'拓跋',
	'夹谷',
	'宰父',
	'谷梁',
	'段干',
	'百里',
	'东郭',
	'南门',
	'呼延',
	'羊舌',
	'微生',
	'梁丘',
	'左丘',
	'东门',
	'西门',
	'南宫',
	'第五'
];

我声明一个this.isDoubleFamilyName用来标记是否为复姓的标记,默认为0,如果是复姓则2,单姓为1,这里是处理逻辑

if (str.length > 2 && doubleFamilyName.indexOf(str.substr(0, 2)) > -1) {
	//这里可以通过一个弹窗来提示用户选择
	//然后根据用户选择来设置this.isDoubleFamilyName的值
} else {
	this.isDoubleFamilyName = 1;
}

接下来需要判断名字中的多音字,注意这里的多音字是指拼写不同,音调不同的忽略。这里需要借助第三方的库来将汉字转为拼音,我使用的是在github上找的一个库,仓库地址在这里,使用方法很简单

import pinyin from 'pinyin';
//获取这个字符串的全部读音
//得到一个二维数组
//数据格式如[ [ 'zhang', 'zhong' ], [ 'xin' ] ,['liu','ni']]
this.py = pinyin(str, {
	heteronym: true,	//打开多音字
	style: pinyin.STYLE_NORMAL	//注音不加声调
});
let py = this.py; 	//这里存全局变量是为了后面可以复用

这里声明一个this.nameSpell用来保存最后的每个字的读音数组

考虑到实际使用中文名转英文名都是转为全大写,这里我也使用了toUpperCase()方法来转换,如不需要自己手动去除这个方法即可

if (py.some(i => i.length > 1)) {	//判断这个二维数组中是否有哪一项含有多音字
	//这里让用户选择具体的读音并赋值给this.nameSpell
	//这里涉及到一个排列组合的问题,具体代码可以参考博客底部的代码参考
} else {
	this.nameSpell = py.map(i => i[0].toUpperCase());
}

现在我们已经将最后的整个拼音方案获取到this.nameSpell,接下来就是处理姓和名的分割了。这里使用this.firstNamethis.lastName分别保存。

if (this.nameSpell.length > 0) {
	if (this.isDoubleFamilyName == 2) {
		this.lastName = this.nameSpell[0] + this.nameSpell[1];
		this.firstName = this.nameSpell.slice(2).join('');
	} else if (this.isDoubleFamilyName == 1) {
		this.lastName = this.nameSpell[0];
		this.firstName = this.nameSpell.slice(1).join('');
	}
}

到此我们已经完成整个从中文名转为英文名的过程。

代码参考

二维数组的排列组合

/** 
* 传入一个二维数组,如[ [ 'zhang', 'zhong' ], [ 'xin' ] ,['liu']]
* 返回[['zhang','xin','liu'],['zhang','zhong','liu']]
*/
function(py) {
	let lengthArr = [];
	let productArr = [];
	let result = [];
	let length = 1;
	for (let i = 0; i < py.length; i++) {
		let len = py[i].length;
		lengthArr.push(len);
		let product = i === 0 ? 1 : py[i - 1].length * productArr[i - 1];
		productArr.push(product);
		length *= len;
	}
	for (let i = 0; i < length; i++) {
		let resultItem = [];
		for (let j = 0; j < py.length; j++) {
			resultItem.push(
				py[j][Math.floor(i / productArr[j]) % lengthArr[j]].toUpperCase()
			);
		}
		result.push(resultItem);
	}
	return result;
}
相关标签: 技巧