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

使用正则表达式屏蔽信用卡号最后4位以外数字(保留连字符)

信用卡号掩码解决方案

需求回顾

对信用卡号进行掩码处理,核心规则:

  • 保留最后4位数字,其余数字替换为x
  • 原始字符串中的连字符(或其他非数字分隔符)需保留原有位置
  • 示例验证:
原始字符串期望输出
1234-5678-9123-4567-891xxxx-xxxx-xxxx-xxx7-891
1234-5678-9123-4567xxxx-xxxx-xxxx-4567
123456789123xxxxxxxx9123

原代码问题分析

你提供的代码存在几个关键问题:

  1. 按字符长度截取前部分:通过CCnumber.Substring(0, CCnumber.Length - 4)截取的是最后4个字符,而非最后4个数字,当最后4个字符包含非数字分隔符时(比如第一个示例的-891),会错误保留不必要的字符,同时遗漏需要掩码的数字。
  2. 正则转义错误:替换数字时使用@"\\d",多了一个不必要的转义符,应该是@"\d"。
  3. 匹配逻辑局限:正则(\\d[\\s|-]?){10,}\\d无法灵活适配所有分隔位置的信用卡号格式。

修正后的解决方案

以下是能覆盖所有场景的C#扩展方法,核心思路是跟踪数字的索引位置,只掩码前N-4个数字(N为总数字数),非数字字符直接保留:

public static string MaskCreditCardNo(this string value)
{
    if (string.IsNullOrWhiteSpace(value))
        return value;

    // 提取字符串中所有数字
    var allDigits = value.Where(char.IsDigit).ToList();
    // 数字数量≤4时无需掩码,直接返回原字符串
    if (allDigits.Count <= 4)
        return value;

    // 标记需要保留的最后4个数字的索引位置
    var keepDigitIndices = new HashSet<int>(Enumerable.Range(allDigits.Count - 4, 4));
    int currentDigitCounter = 0;
    var resultBuilder = new StringBuilder();

    foreach (var c in value)
    {
        if (char.IsDigit(c))
        {
            // 判断当前数字是否属于需要保留的最后4位
            if (keepDigitIndices.Contains(currentDigitCounter))
                resultBuilder.Append(c);
            else
                resultBuilder.Append('x');
            
            currentDigitCounter++;
        }
        else
        {
            // 非数字字符直接保留原位置
            resultBuilder.Append(c);
        }
    }

    return resultBuilder.ToString();
}

逻辑说明

  1. 提取数字:先把字符串中所有数字提取出来,统计总数量,判断是否需要掩码(数字数>4才需要)。
  2. 标记保留位置:通过索引范围确定最后4个数字的位置,避免重复数字导致的判断错误。
  3. 遍历构建结果:逐个字符遍历原字符串,数字字符根据索引判断是否替换为x,非数字字符直接保留,完美匹配原始格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:48:13