Java手机号掩码实现问题:需保留前4位后3位,现有代码结果不符预期
手机号掩码正确实现方案
你的需求是保留手机号前4位和后3位,中间用掩码替换(如0813*****129),但现有代码的问题在于第二个正则表达式逻辑错误:\\d(?=\\d{4})会匹配所有后面仍有4个数字的字符,导致除最后4位外的所有数字都被替换成X,最终得到XXXXXXXX6600这类不符合预期的结果。
正确实现方式
以下提供两种可靠的实现方案,均先处理手机号前缀(适配印尼常见的+628/628/08格式),再完成掩码逻辑:
方案1:字符串拼接(直观易读)
public static String maskingPhoneNumber(String value) { // 清理所有非数字字符 String cleaned = value.replaceAll("[^\\d]", ""); // 统一手机号前缀:+628/628 转为 08 if (cleaned.startsWith("628")) { cleaned = "0" + cleaned.substring(2); } else if (cleaned.startsWith("+628")) { cleaned = "0" + cleaned.substring(3); } // 长度不足7位(前4+后3)时直接返回原清理后的值 if (cleaned.length() < 7) { return cleaned; } // 提取前4位、后3位,生成对应长度的掩码 String prefix = cleaned.substring(0, 4); String suffix = cleaned.substring(cleaned.length() - 3); String mask = "*".repeat(cleaned.length() - 4 - 3); return prefix + mask + suffix; }
方案2:正则表达式(简洁高效)
public static String maskingPhoneNumber(String value) { // 清理并统一前缀 String cleaned = value.replaceAll("[^\\d]", ""); if (cleaned.startsWith("628")) { cleaned = "0" + cleaned.substring(2); } else if (cleaned.startsWith("+628")) { cleaned = "0" + cleaned.substring(3); } if (cleaned.length() < 7) { return cleaned; } // 正则逻辑:仅替换前4位之后、后3位之前的数字为* return cleaned.replaceAll("(?<=^\\d{4})\\d(?=\\d{3})", "*"); }
正则说明
方案2中的正则(?<=^\\d{4})\\d(?=\\d{3}):
(?<=^\\d{4}):正向零宽断言,确保匹配的数字位于开头4位数字之后\\d:要替换为*的目标数字(?=\\d{3}):正向零宽断言,确保匹配的数字位于末尾3位数字之前
这样就能精准替换中间需要掩码的部分,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Putra Irawan
相关产品推荐
相关产品推荐

