
手机号校验用 Regex.IsMatch 别直接写死 pattern
国内手机号基本是 1 开头、第二位常见 3–9、共 11 位,但不能只写 ^1[3-9]\d{9}$ —— 这会误判已停用号段(比如 170/171 虚拟运营商号段实际已大量启用),也漏掉新开放的 19x 号段。更稳妥的做法是明确覆盖当前有效号段:
用 ^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$,其中 4[01456879] 排除已废弃的 42/43/47(部分虚拟号段)注意:正则末尾必须加 $,否则 "13812345678abc" 也会通过别在循环里反复编译正则,用 static readonly Regex 缓存实例,否则性能明显下降
邮箱校验别信网上抄来的“超长正则”
RFC 5322 规范的邮箱正则长达上千字符,实际项目根本不用那么严格。业务上真正需要拦住的是明显非法格式(比如无 @、双 @、@ 后无点、空域名),而不是验证 "test@example.com." 是否合法。
推荐用:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$+ 表示本地部分至少一个字符,避免 @domain.com 通过域名后缀限制 {2,} 是为了过滤单字母后缀(如 user@x.c),但要注意国际化域名(IDN)需先 Punycode 转换再校验如果后端要发邮件,光靠正则不够,必须配合 SMTP 连通性探测或 DNS MX 记录查询
身份证号校验必须做最后一位加权校验,不能只看长度和数字
18 位身份证不是纯数字——最后一位可能是 X(罗马数字 10),且前 17 位加权求和 mod 11 必须匹配对应校验码表。只用 ^d{17}[dXx]$ 是严重漏洞。
先用正则粗筛:^\d{17}[\dXx]$再算加权和:权重数组 new int[] {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2},前 17 位数字 × 对应权重,求和后对 11 取模余数 0–10 对应校验码 "10X98765432",比如余数是 2,最后一位必须是 ‘X’ 或 ‘x’别忽略地区码有效性:前 6 位得在公安部《行政区划代码》表中存在(可加载为字典缓存,不建议每次查库)
三个校验放一起时,RegexOptions.Compiled 反而拖慢启动速度
如果只是偶尔校验(比如用户注册提交时),用 RegexOptions.Compiled 不仅没收益,还会增加 JIT 编译开销;只有高频调用(如日志解析)才值得。
推荐写法:Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase),简单场景够用若 pattern 固定且复用频繁,定义为 static readonly Regex 并省略 RegexOptions.Compiled(.NET Core 3.0+ 默认已优化)手机号和身份证号校验建议封装成独立方法,内部先做长度/首字符等快速失败判断,再进正则或算法校验,避免无效正则执行
身份证最后一位的大小写容错、邮箱本地部分的连续点号(如 ab..cd@example.com)是否允许、手机号是否接受带空格或短横线的输入——这些边界都得按你业务规则明确,不能全扔给正则扛。

评论(0)