应使用精准号段正则^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])d{8}$校验手机号,邮箱用^[a-za-z0-9._%+-]+@[a-za-z0-9.-]+.[a-za-z]{2,}$,身份证须结合正则粗筛与加权校验算法。

手机号校验用 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)是否允许、手机号是否接受带空格或短横线的输入——这些边界都得按你业务规则明确,不能全扔给正则扛。










