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

如何用正则表达式实现电话号码部分字符替换为*的掩码效果?

解决电话号码掩码问题的正确正则方案

你的核心问题是原正则没有排除括号内的数字,且没有精准控制括号外数字的替换范围(仅保留前2位和最后2位)。下面是具体的解决方案:

明确掩码规则

  • 括号()内的数字完全保留,不做任何替换
  • 括号外的数字:
    • 保留前2位数字
    • 保留最后2位数字
    • 中间所有数字替换为*
    • 原有的非数字分隔符(空格、-等)保持不变

原正则的问题分析

你使用的(?<!\()\d(?!\d?$)会匹配所有不在(之后的数字(且不是倒数第一个数字),这就导致括号内的123中,2和3因为前面不是(,会被错误替换成*,最终得到+(1**) ***-***45,不符合预期。

正确实现方案

我们需要先区分括号内/外的内容,只处理括号外的数字,并且精准控制替换范围。以下是两种常见语言的实现:

Python 实现

import re

def mask_phone_number(phone):
    # 提取括号外的所有数字序列
    non_parentheses_digits = re.findall(r'(?<=\))\d|\d(?=\()', phone)
    total_digits = len(non_parentheses_digits)
    
    # 数字少于等于4位时无需掩码
    if total_digits <= 4:
        return phone
    
    # 标记哪些数字需要保留,哪些替换为*
    digit_map = {}
    for idx in range(total_digits):
        if idx < 2 or idx >= total_digits - 2:
            digit_map[idx] = non_parentheses_digits[idx]
        else:
            digit_map[idx] = '*'
    
    # 遍历原字符串,构建结果
    result = []
    in_parentheses = False
    current_digit_idx = 0
    
    for char in phone:
        if char == '(':
            in_parentheses = True
            result.append(char)
        elif char == ')':
            in_parentheses = False
            result.append(char)
        elif in_parentheses:
            result.append(char)
        elif char.isdigit():
            result.append(digit_map[current_digit_idx])
            current_digit_idx += 1
        else:
            result.append(char)
    
    return ''.join(result)

# 测试示例
print(mask_phone_number('+(123) 123-12345'))  # 输出:+(123) 12*-***45
print(mask_phone_number('+(123) 123 12 12345'))  # 输出:+(123) 12* ** ***45

JavaScript 实现

function maskPhoneNumber(phone) {
    // 提取括号外的所有数字
    const nonParenthesesDigits = phone.match(/(?<=\))\d|\d(?=\()/g) || [];
    const totalDigits = nonParenthesesDigits.length;
    
    if (totalDigits <= 4) return phone;
    
    let currentIndex = 0;
    // 替换括号外的目标数字
    return phone.replace(/(?<=\))\d|\d(?=\()/g, () => {
        currentIndex++;
        // 保留前2位和最后2位,其余替换为*
        if (currentIndex <= 2 || currentIndex > totalDigits - 2) {
            return nonParenthesesDigits[currentIndex - 1];
        }
        return '*';
    });
}

// 测试示例
console.log(maskPhoneNumber('+(123) 123-12345')); // 输出:+(123) 12*-***45
console.log(maskPhoneNumber('+(123) 123 12 12345')); // 输出:+(123) 12* ** ***45

纯正则替换方案(无回调)

如果你的环境不支持正则回调,可以分三步处理:

  1. 先把括号内的内容临时替换为占位符,避免干扰
  2. 对括号外的数字进行掩码处理
  3. 恢复括号内的内容

示例(Python):

import re

def mask_phone_simple(phone):
    # 第一步:替换括号内内容为占位符
    placeholder = "TEMP_PAREN_CONTENT"
    temp = re.sub(r'\((\d+)\)', placeholder, phone)
    # 提取括号外的数字
    digits = re.findall(r'\d', temp)
    total = len(digits)
    if total <=4:
        return phone
    # 生成掩码后的数字序列
    masked_digits = digits[:2] + ['*']*(total-4) + digits[-2:]
    # 替换回数字
    idx =0
    result = []
    for c in temp:
        if c.isdigit():
            result.append(masked_digits[idx])
            idx +=1
        else:
            result.append(c)
    # 恢复括号内内容
    original_paren = re.search(r'\((\d+)\)', phone).group(1)
    return ''.join(result).replace(placeholder, f'({original_paren})')

# 测试
print(mask_phone_simple('+(123) 123-12345'))  # 输出:+(123) 12*-***45

内容的提问来源于stack exchange,提问作者Yevhenii Avram

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:10:59