// 最近收到一个需求,判定同名同姓
// 例如 张三==张 三 == 三张 ==三 张==zhangsan ==zhang san ==Zhang san==sanzhang==San zhang
// 用法
console.log("1", isNameSame('张三', 'San zhang')); // true
// tiny-pinyin是一个汉字转拼音的库,需要自己引入 ,传送门https://www.npmjs.com/package/tiny-pinyin
const pinyin = require('tiny-pinyin')
/**
* 判断两个名字是否相同
* @export
* @param {string} str1
* @param {string} str2
* @returns {boolean}
*/
export function isNameSame(str1:string, str2:string):boolean {
// 去掉空格 并全部转小写
str1 = allTrim(str1.toLowerCase())
str2 = allTrim(str2.toLowerCase())
// 两个 不全是中文 也不全是英文, 如: ab张三或者是(含有标点符号) _张三
if (!isAllChn(str1) && !isNoChn(str1) && !isAllChn(str2) && !isNoChn(str2) ) {
return str1==str2
}
// 两个都是中文名
if (isAllChn(str1) && isAllChn(str2)) {
return isDoubleCnNameSame(str1, str2)
}
// 第一个中文 第二拼音
if (isAllChn(str1) && isNoChn(str2)) {
// isAllChn(str1) 汉字放在第二参数中
return hanZiVsPinyin(str2, str1)
}
// 第一个拼音 第二个中文
if (isNoChn(str1) && isAllChn(str2)) {
return hanZiVsPinyin(str1, str2)
}
// 两个都是拼音,或者是英文名
if (isNoChn(str1) && isNoChn(str2) && str1 == str2) {
return true
}
// 两个都是拼音,或者是英文名,但直接对比并不相等 例如 zhangsan vs sanzhang
if (isNoChn(str1) && isNoChn(str2) && str1 != str2) {
return pinyinVsPinyin(str1, str2)
}
// 如果以上情况都不是 直接返回
return str1==str2
}
/**
* 两个中文名 是否同名同姓
* @param {string} str1
* @param {string} str2
* @returns {boolean}
*/
function isDoubleCnNameSame(str1:string, str2:string):boolean {
if (str1 == str2) {
return true
} else {
// 获取最后一个字符
let last1 = str1.substr(str1.length - 1, 1)
// 删除最后一个字符串,获取新的字符串
let s1 = str1.substr(0, str1.length - 1)
// 将最后一个字符串放到前面
let turnPositon_1 = last1 + s1
let last2 = str2.substr(str2.length - 1, 1)
let s2 = str2.substr(0, str2.length - 1)
let turnPositon_2 = last2 + s2
// 不管两个参数,哪个名字是姓氏颠倒都可以,有一种符合就是相等
return turnPositon_1 == str2 || str1 == turnPositon_2
}
}
/**
* 一个汉字一个拼音,调用前判断好哪个是汉字 哪个是拼音
* @param {string} pinyin_name 拼音
* @param {string} cn_name 汉字
* @returns {boolean}
*/
function hanZiVsPinyin(pinyin_name:string, cn_name:string):boolean{
// (汉字,间隔符,是否小写)
let pinyin_name2 = pinyin.convertToPinyin(cn_name,"",true)
if (pinyin_name == pinyin_name2) {
return true
} else {
return pinyinVsPinyin(pinyin_name, pinyin_name2)
}
}
/**
* 如果两个拼音是互相倒置,需要单个字母逐渐递增的方式 前后倒置后对比
* @param {string} pinyin_name
* @param {string} pinyin_name2
* @returns {boolean}
*/
function pinyinVsPinyin(pinyin_name:string, pinyin_name2:string):boolean {
// 行成一个拼音,至少需要一个字母,依次截取多一个字母
let isSame = false
for (var i = 0; i < pinyin_name.length; i++) {
// i+1==截取的长度 比如(zhangsan,sanzhang)依次截取z zh zha zhan zhang 放到末尾和另外一个名字比对
let frontStr = pinyin_name.substr(0, i + 1)
let lastStr = pinyin_name.substr(i + 1, pinyin_name.length - 1)
let newName = lastStr + frontStr
if (newName == pinyin_name2) {
isSame = true
break
}
}
return isSame
}
/**
* 去掉所有空格
* @param {string} str
* @returns {string}
*/
function allTrim(str:string):string{
return str.replace(/\s/g, "")
}
/**
* 是否全是汉字
* @param {string} str
* @returns {boolean}
*/
function isAllChn(str:string):boolean {
var reg = /^[\u4E00-\u9FA5]+$/;
if (!reg.test(str)) {
// console.log("不全是中文");
return false;
} else {
// console.log("全是中文");
return true;
}
}
/**
* 是否全是英文
* @param {string} str
* @returns {boolean}
*/
function isNoChn(str:string):boolean {
if (/.*[\u4e00-\u9fa5]+.*$/.test(str)) {
// console.log('有汉字');
return false;
} else {
// console.log('有汉字');
return true;
}
}
/**
* 获取字符编码
* @param {string} str
* @returns {number[]}
*/
function getCharCode(str:string):number[] {
var bytes = [];
var len = str.length;
for (var i = 0; i < len; ++i) {
var code = str.charCodeAt(i);
bytes.push(code)
}
return bytes;
}
网友评论