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:保留的后几位数字
方法执行流程:
参数校验
JAVAif (phone == null || phone.equals("")) throw new BadRequestException("电话号码不能为空");检查电话号码是否为空
清洗电话号码
JAVAphone = phone.replaceAll("-", "").trim();移除所有连字符并去除首尾空格
长度验证
JAVAint length = prefix + mosaic + suffix; if (phone.length() != length) throw new BadRequestException("电话号码长度或入参不合法");验证电话号码长度与参数之和是否匹配
格式化处理(核心逻辑)
JAVAreturn 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:保留第二个分组(后缀)
使用示例:
// 输入: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);
注意事项:
- 该方法会先移除电话号码中的连字符
- 确保
prefix + mosaic + suffix等于电话号码的实际长度 - 如果
mosaic为0,则不会显示星号 - 使用
Math.max(0, mosaic)确保星号数量不为负数
(\d{" + prefix + "}) () 代表分组吗?
是的,你说的完全正确!
在正则表达式中,圆括号 () 表示分组(capturing group),它有两个主要作用:
1. 分组作用
将括号内的模式作为一个整体单元,方便进行量词操作或逻辑控制。
2. 捕获作用(这里是关键)
捕获匹配的内容,可以在后续操作中引用。
在这个方法中的具体应用:
"(\\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位数字
在替换中的使用:
"$1" + "*".repeat(mosaic) + "$2"
$1:引用第一个分组的内容(前3位数字)"*".repeat(mosaic):生成mosaic个星号$2:引用第二个分组的内容(后4位数字)
示例说明:
输入:phone = "13812345678",prefix=3,mosaic=4,suffix=4
正则匹配:
- 分组1(
$1):"138" - 中间部分:
"1234"(被匹配但不捕获) - 分组2(
$2):"5678"
- 分组1(
替换结果:
$1→"138""*".repeat(4)→"****"$2→"5678"- 最终结果:
"138****5678"
小提示:
如果不希望捕获分组,可以使用非捕获分组语法 (?:...),但这里我们需要引用分组内容,所以必须使用捕获分组。
这就是为什么这个方法能"保留前缀和后缀,只替换中间部分"的原因!