如何用Zod去除字符串内空格并验证法国格式手机号
法国手机号Zod验证与格式化方案
要实现宽松输入(允许含空格)并最终输出xx xx xx xx xx格式的法国手机号验证,你可以通过以下步骤调整Zod schema:
完整解决方案代码
import { z } from "zod"; const frenchPhoneSchema = z.string() // 第一步:移除所有非数字字符(支持空格、破折号等任意分隔符) .transform((val) => val.replace(/\D/g, '')) // 第二步:验证清理后的字符串是10位纯数字 .refine((cleanedVal) => cleanedVal.length === 10, { message: "手机号必须包含10位数字" }) // 第三步:格式化为xx xx xx xx xx的标准格式 .transform((cleanedVal) => { return cleanedVal.match(/.{1,2}/g)?.join(' ') || cleanedVal; });
代码说明
- 清理输入:使用
replace(/\D/g, '')移除所有非数字字符,不管用户输入的是空格、破折号还是其他符号,都能得到纯数字字符串,实现真正的宽松输入。 - 验证长度:通过
refine确保清理后的字符串长度恰好为10位,这是法国手机号的标准长度。 - 格式化输出:用
match(/.{1,2}/g)将10位数字拆分为每两位一组,再用空格连接,得到符合要求的格式。
测试用例
// 各种合法输入都会输出标准格式 console.log(frenchPhoneSchema.parse("0123456789")); // "01 23 45 67 89" console.log(frenchPhoneSchema.parse("01 23 45 67 89")); // "01 23 45 67 89" console.log(frenchPhoneSchema.parse("01-23-45-67-89")); // "01 23 45 67 89" console.log(frenchPhoneSchema.parse(" 0123456789 ")); // "01 23 45 67 89" // 非法输入会抛出错误 // frenchPhoneSchema.parse("012345678"); // 错误:手机号必须包含10位数字 // frenchPhoneSchema.parse("01a23456789"); // 错误:手机号必须包含10位数字
原代码问题分析
- 你之前的
trim()仅能移除首尾空格,无法处理中间的空格,导致带空格的输入(如01 23 45 67 89)trim后长度为14,触发了val.length!==10的错误判断,不符合宽松输入的需求。 - 单独使用
trim()既不会清理中间空格,也不会格式化字符串,自然无法得到你想要的结果。
可选:仅允许空格作为分隔符
如果只想允许空格(拒绝其他非数字符号),可以修改清理逻辑为仅移除空格,再验证纯数字:
const frenchPhoneSchema = z.string() .transform((val) => val.replace(/\s/g, '')) // 只移除空格 .refine((cleanedVal) => /^\d{10}$/.test(cleanedVal), { message: "手机号必须是10位数字(可包含空格)" }) .transform((cleanedVal) => cleanedVal.match(/.{1,2}/g)?.join(' ') || cleanedVal);
内容的提问来源于stack exchange,提问作者Meaulnes
相关产品推荐
相关产品推荐

