You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 09:32:52