Java电话号码格式化与脱敏方法

小豆丁 29天前 ⋅ 57 阅读
聊天记录
头像

public static String phoneFormat(String phone, int prefix, int mosaic, int suffix) { if (phone == null || phone.equals("")) throw new BadRequestException("电话号码不能为空"); phone = phone.replaceAll("-", "").trim(); int length = prefix + mosaic + suffix; if (phone.length() != length) throw new BadRequestException("电话号码长度或入参不合法"); return phone.replaceAll("(\d{" + prefix + "})\d{" + mosaic + "}(\d{" + suffix + "})", "$1" + "*".repeat(Math.max(0, mosaic)) + "$2"); } 解释一下

头像

这是一个用于格式化电话号码的Java方法,主要功能是将电话号码的中间部分替换为星号(*)以隐藏部分号码。

方法参数说明:

  • phone:原始电话号码
  • prefix:保留的前几位数字
  • mosaic:需要隐藏的中间位数(用*替换)
  • suffix:保留的后几位数字

方法执行流程:

  1. 参数校验

    JAVA
    if (phone == null || phone.equals("")) 
        throw new BadRequestException("电话号码不能为空");
    

    检查电话号码是否为空

  2. 清洗电话号码

    JAVA
    phone = phone.replaceAll("-", "").trim();
    

    移除所有连字符并去除首尾空格

  3. 长度验证

    JAVA
    int length = prefix + mosaic + suffix;
    if (phone.length() != length) 
        throw new BadRequestException("电话号码长度或入参不合法");
    

    验证电话号码长度与参数之和是否匹配

  4. 格式化处理(核心逻辑)

    JAVA
    return phone.replaceAll("(\\d{" + prefix + "})\\d{" + mosaic + "}(\\d{" + suffix + "})", 
                           "$1" + "*".repeat(Math.max(0, mosaic)) + "$2");
    

正则表达式解析:

  • (\\d{" + prefix + "}):匹配前prefix位数字,作为分组1
  • \\d{" + mosaic + "}:匹配中间的mosaic位数字
  • (\\d{" + suffix + "}):匹配后suffix位数字,作为分组2

替换模式:

  • $1:保留第一个分组(前缀)
  • "*".repeat(Math.max(0, mosaic)):用mosaic个星号替换中间部分
  • $2:保留第二个分组(后缀)

使用示例:

JAVA
// 输入:13812345678, prefix=3, mosaic=4, suffix=4
// 输出:138****5678
String result = phoneFormat("13812345678", 3, 4, 4);

// 输入:010-8765-4321, prefix=3, mosaic=4, suffix=4
// 输出:010****4321
String result2 = phoneFormat("010-8765-4321", 3, 4, 4);

注意事项:

  1. 该方法会先移除电话号码中的连字符
  2. 确保prefix + mosaic + suffix等于电话号码的实际长度
  3. 如果mosaic为0,则不会显示星号
  4. 使用Math.max(0, mosaic)确保星号数量不为负数
头像

(\d{" + prefix + "}) () 代表分组吗?

头像

是的,你说的完全正确!

在正则表达式中,圆括号 () 表示分组(capturing group),它有两个主要作用:

1. 分组作用

将括号内的模式作为一个整体单元,方便进行量词操作或逻辑控制。

2. 捕获作用(这里是关键)

捕获匹配的内容,可以在后续操作中引用。

在这个方法中的具体应用:

JAVA
"(\\d{" + prefix + "})\\d{" + mosaic + "}(\\d{" + suffix + "})"

假设 prefix=3, mosaic=4, suffix=4,这个正则表达式就是:

(\\d{3})\\d{4}(\\d{4})

分组结果:

  • 分组1(第一个括号):(\\d{3}) - 匹配前3位数字
  • 中间部分:\\d{4} - 匹配4位数字,但没有括号,所以不捕获
  • 分组2(第二个括号):(\\d{4}) - 匹配后4位数字

在替换中的使用:

JAVA
"$1" + "*".repeat(mosaic) + "$2"
  • $1:引用第一个分组的内容(前3位数字)
  • "*".repeat(mosaic):生成mosaic个星号
  • $2:引用第二个分组的内容(后4位数字)

示例说明:

输入:phone = "13812345678"prefix=3mosaic=4suffix=4

  1. 正则匹配:

    • 分组1($1):"138"
    • 中间部分:"1234"(被匹配但不捕获)
    • 分组2($2):"5678"
  2. 替换结果:

    • $1"138"
    • "*".repeat(4)"****"
    • $2"5678"
    • 最终结果:"138****5678"

小提示:

如果不希望捕获分组,可以使用非捕获分组语法 (?:...),但这里我们需要引用分组内容,所以必须使用捕获分组。

这就是为什么这个方法能"保留前缀和后缀,只替换中间部分"的原因!

全部评论: 0

    我有话说: