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

求PCRE正则表达式:匹配8/9/12位数字并仅保留后4位未掩码

PCRE正则实现指定长度数字串掩码需求

需求

编写PCRE正则,仅匹配数字总数为8、9或12位的字符串(数字间可包含空格、连字符-、逗号,作为分隔符),将除最后4位之外的数字替换为掩码字符(如*),具体规则:

  • 8位数字:前4位掩码,保留最后4位
  • 9位数字:前5位掩码,保留最后4位
  • 12位数字:前8位掩码,保留最后4位

现有问题

你当前编写的正则仅能匹配前5位数字,既满足不了不同长度的掩码要求,也无法处理数字间的分隔符。

解决办法

带分隔符保留的方案(推荐)

通过正则匹配目标串,结合回调函数处理替换,可保留原分隔符的位置:

匹配正则

/(?<=\D|^)([\d\s,-]*)(\d{4})(?=\D|$)/gmi

替换逻辑(PHP示例)

$str = preg_replace_callback(
    '/(?<=\D|^)([\d\s,-]*)(\d{4})(?=\D|$)/gmi',
    function($matches) {
        $fullStr = $matches[1] . $matches[2];
        // 提取纯数字部分
        $pureDigits = preg_replace('/[\s,-]/', '', $fullStr);
        $digitLength = strlen($pureDigits);
        
        // 仅处理符合长度要求的串
        if (!in_array($digitLength, [8, 9, 12])) return $fullStr;
        
        // 计算需要掩码的数字数量
        $maskCount = $digitLength - 4;
        // 将前缀部分的指定数量数字替换为*
        $maskedPrefix = preg_replace('/\d/', '*', $matches[1], $maskCount);
        return $maskedPrefix . $matches[2];
    },
    $str
);

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

若不想使用回调函数,可分三次替换处理不同长度的字符串:

// 处理8位数字串:替换前4个数字为*
$str = preg_replace('/(?<=\D|^)(?:[\s,-]*\d){4}(?=(?:[\s,-]*\d){4}(?:\D|$))/', '****', $str);
// 处理9位数字串:替换前5个数字为*
$str = preg_replace('/(?<=\D|^)(?:[\s,-]*\d){5}(?=(?:[\s,-]*\d){4}(?:\D|$))/', '*****', $str);
// 处理12位数字串:替换前8个数字为*
$str = preg_replace('/(?<=\D|^)(?:[\s,-]*\d){8}(?=(?:[\s,-]*\d){4}(?:\D|$))/', '********', $str);

无分隔符简化方案

若不需要保留分隔符,可先去除所有非数字字符,再进行掩码:

// 匹配8/9/12位数字串的前缀部分
/(?<=\D|^)(\d{4})(?=\d{4}$)|(?<=\D|^)(\d{5})(?=\d{4}$)|(?<=\D|^)(\d{8})(?=\d{4}$)/gmi

替换时对应长度替换为掩码:

  • 匹配到的4位数字→****
  • 匹配到的5位数字→*****
  • 匹配到的8位数字→********

效果示例

原始串掩码后结果
12345678****5678
123-456-789--789
1234,5678,9012,,9012
12 345 6789** *** 6789

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:17:57