携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
前言
页面展示时,一些隐私的个人信息不能完整的展示出来,需要进行隐藏处理。
如手机号码是 '12345678912',那么显示时,会将保留头部的两位数字和尾部的四位数字,在页面上显示为 '12*****8912';姓名偶尔也需要这么处理,比如 '派大星' 显示为 '派*星',身份证号等其他隐私信息也需要进行部分的隐藏。
基本思路
这种需求很适合使用正则表达式进行处理,只需要匹配出中间部分的字符串,然后替换成 * 再显示即可。
正则表达式
正则的匹配思路:
- 匹配的字符串不一定是数字,有可能是中文,英文等等,所以使用
.,表示匹配任何字符; - 因为字符串的长度不固定,不能直接在正则中写死长度;所以需要确定的是被匹配字符串的位置,根据位置进行匹配;
- 匹配的位置也根据项目需求而定,大抵都是保留前几位和最后的几位字符,所以可以使用
(?<=)和(?=)进行确定中间字符串的起始和结束位置。
假定头部保留 2 位字符,尾部保留 2 位字符,则正则表达式如下:
// (?<=.{2}) 表示保留最开始的两位字符,也是匹配字符的起始位置
// (?=.{2}) 表示保留后的两位字符,也是匹配字符的结束位置
// .{1} 表示匹配除去头尾保留部分的其他字符,只匹配一个
const reg = /(?<=.{2}).{1}(?=.{2})/g
可以正常匹配。
注意:
中间的.{1}可所以省略掉{1},但不能写成.{1,}、.*、.+等,从而匹配多个。
因为这种只是隐藏字符,并没有减少字符的数量,如123456,应该隐藏显示为12**56,而显示为12*56看上去就不合理了。
当然,也可以一次性捕获,但这样需要在replace的回调函数中进行特殊处理。
封装函数
上面已经实现了正则表达式,接下来就是将匹配字符替换掉。并且为了方便使用,封装成函数调用的形式,代码如下:
/**
* 将传入的字符串中间部分替换为 "*",以达到隐藏信息的目的
* @param { string } originString 需要处理的字符串
* @param { number } startRetain 开头保留不更改的字符数量
* @param { number } endRetain 结尾保留不更改的字符数量
* @param { string } subString 代替字符,用于替换需要被隐藏的字符
* @return { string } 返回处理好的字符串,如果传入值不符合要求或者其他问题,则返回空字符串
*/
function replaceToHidden (originString, startRetain = 1, endRetain = 1, subString = '*') {
// 类型检测
if (
!originString ||
typeof originString !== 'string' ||
typeof startRetain !== 'number' ||
typeof endRetain !== 'number' ||
typeof subString !== 'string'
) {
console.error('请检查传入的参数是否正确 !')
return ''
}
// 动态生成正则表达式
const reg = new RegExp(`(?<=.{${startRetain}}).{1}(?=.{${endRetain}})`, 'g')
// 返回替换结果
return originString.replace(reg, subString)
}
测试结果:
console.log(replaceToHidden('12345678912', 2, 4))
// 12*****8912
console.log(replaceToHidden('派大星'))
// 派*星