JS-隐藏手机号的中间部分

1,048 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

前言

页面展示时,一些隐私的个人信息不能完整的展示出来,需要进行隐藏处理。

如手机号码是 '12345678912',那么显示时,会将保留头部的两位数字和尾部的四位数字,在页面上显示为 '12*****8912';姓名偶尔也需要这么处理,比如 '派大星' 显示为 '派*星',身份证号等其他隐私信息也需要进行部分的隐藏。

基本思路

这种需求很适合使用正则表达式进行处理,只需要匹配出中间部分的字符串,然后替换成 * 再显示即可。

正则表达式

正则的匹配思路:

  1. 匹配的字符串不一定是数字,有可能是中文,英文等等,所以使用 .,表示匹配任何字符;
  2. 因为字符串的长度不固定,不能直接在正则中写死长度;所以需要确定的是被匹配字符串的位置,根据位置进行匹配;
  3. 匹配的位置也根据项目需求而定,大抵都是保留前几位和最后的几位字符,所以可以使用 (?<=)(?=) 进行确定中间字符串的起始和结束位置。

假定头部保留 2 位字符,尾部保留 2 位字符,则正则表达式如下:

// (?<=.{2}) 表示保留最开始的两位字符,也是匹配字符的起始位置
// (?=.{2}) 表示保留后的两位字符,也是匹配字符的结束位置
// .{1} 表示匹配除去头尾保留部分的其他字符,只匹配一个
const reg = /(?<=.{2}).{1}(?=.{2})/g

微信截图_20220807134121.png 可以正常匹配。

注意:
中间的 .{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('派大星'))
// 派*星