正则处理手机号:保留开头+及动态传入正则参数的实现方法
解决手机号掩码的两个问题:保留开头+和动态传入正则参数
1. 保留开头的单个+,移除后续非数字字符
原代码里的/\D/g会删除所有非数字字符,包括开头的+。要保留开头仅有的一个+,可以拆分两步处理:
- 先提取开头的可选+(最多保留一个),清空开头+之后的所有非数字
- 再删除剩余内容里的所有非数字字符
修改后的清理逻辑:
// 保留开头的单个+(如果有),然后移除其他所有非数字 const cleaned = value.replace(/^(\+)?\D*/, '$1').replace(/\D/g, '');
解释:/^(\+)?\D*/匹配字符串开头的可选+,并保留这个+,同时清空开头+后面跟着的所有非数字;后续的/\D/g把剩余部分的非数字全部删除,最终只保留开头一个+和所有数字。
2. 动态传入code参数到正则表达式
正则字面量(/.../)无法直接嵌入变量,必须用RegExp构造函数动态生成正则规则。注意构造函数里的正则字符串需要转义反斜杠(比如\d要写成\\d),同时按需添加匹配标志(比如全局匹配g)。
比如原代码里的/(\d{code})(\d)/要改成:
new RegExp(`(\\d{${code}})(\\d)`, 'g')
完整修正后的代码
结合上述两点,调整掩码逻辑以匹配预期格式:
const maskPhone = (value, code) => { // 第一步:清理输入,保留开头单个+和所有数字 let cleaned = value.replace(/^(\+)?\D*/, '$1').replace(/\D/g, ''); // 分离开头的+和数字部分,避免干扰掩码规则 const hasPlus = cleaned.startsWith('+'); let numPart = hasPlus ? cleaned.slice(1) : cleaned; // 第二步:动态应用code参数的正则替换 if (code > 0) { numPart = numPart.replace(new RegExp(`(\\d{${code}})(\\d)`, 'g'), '($1) $2'); } // 第三步:处理后续分段,匹配预期的"32 323 232"格式 numPart = numPart.replace(/(\d{2})(\d)/, '$1 $2') .replace(/(\d{3})(\d{3})$/, '$1 $2'); // 拼接回开头的+ return hasPlus ? `+${numPart}` : numPart; }; // 测试示例:传入code=3,输出符合预期结果 console.log(maskPhone('++32332+323232', 3)); // 输出:+(323) 32 323 232
说明:
- 输入
++32332+323232会被清理为+32332323232,再经过掩码处理得到目标格式 - 如果code参数传入其他值(比如4),会自动调整开头括号内的数字位数,例如code=4时输出
+(3233) 2 323 232
内容的提问来源于stack exchange,提问作者DevOverflow
相关产品推荐
相关产品推荐

