最近在常规迭代中遇到一个很小很小的问题 ---- 半角符号转全角符号,全角符号转半角符号
【前言】工作中会经常涉及到这类型需求,本文从unicode进阶过渡到符号转换的实现,可以耐心阅读下去,尽可能讲的有趣一些,如有问题也可以一起交流学习,本人工作经验很少,目前也在不断学习中,若下面的内容有错误,请各位大佬指正,理性讨论,谢谢☃️
【备注】这里仅讨论一些标点符号的转化,其他的转化请自行查一下UTF-16 码元。
基础知识
UTF-16是Unicode字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为storage format)的一种实现方式。 即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。
因此每个字符都对应有一个UTF-16编码,半角符号:,(英文逗号,对应的就是44),全角符号:,(中文逗号,对应的就是65292)
charCodeAt和fromCharCode
String的 charCodeAt() 方法返回一个整数,表示给定索引处的 UTF-16 码元,其值介于 0 和 65535 之间。
// 输出:65
"ABC".charCodeAt(0)
// 输出:44
",".charCodeAt(0)
// 输出:65292
",".charCodeAt(0)
String.fromCharCode()** 静态方法返回由指定的 UTF-16 码元序列创建的字符串。
// 输出:,
String.fromCharCode(44)
','
// 输出:,
String.fromCharCode(65292)
熟悉一下上面的两个方法,其实你已经会进行转换了,无非就是UTF-16和字符之间的相互转换罢了。
全角转半角
重点:全角符号位于UTF-16表的65280-65375之间,在这个范围内都是全角符号,全角符号与半角符号相差65248,如果不清楚的话,可以用上面的charCodeAt输出对应的数据进行计算即可。
全角的空格和半角的空格相差12256。
将字符串丢入循环中,找到对应的字符进行转换匹配即可
function allToHalf(str: string) {
let tmp = "";
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) == 12288) {
tmp += String.fromCharCode(str.charCodeAt(i) - 12256);
continue;
} else if (str.charCodeAt(i) > 65280 && str.charCodeAt(i) < 65375) {
tmp += String.fromCharCode(str.charCodeAt(i) - 65248);
} else {
tmp += String.fromCharCode(str.charCodeAt(i));
}
}
return tmp;
}
半角转全角
function halfToAll(str: string, space = true) {
let tmp = "";
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) == 32) {
if (space) {
tmp = tmp + String.fromCharCode(12288);
} else {
tmp = tmp + "";
}
} else if (str.charCodeAt(i) < 127) {
tmp = tmp + String.fromCharCode(str.charCodeAt(i) + 65248);
} else {
tmp += str[i];
}
}
return tmp;
}
总结
关键在于编码范围和基本方法的使用上,并没有太大的难点,如果上面写的有问题,欢迎各位大佬指教。