最直接的办法是用 Regex.IsMatch 配合平衡可读性与准确性的正则:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$,它覆盖主流合法格式(含+tag)、拒绝明显非法形式(如@@、user@a.b),但仅做语法校验,不查DNS或MX;应先判空再Trim后匹配,避免空格干扰;MailAddress构造函数因兼容过宽、异常模糊且有开销,不适合作为校验手段;IDN需单独对域名部分用IdnMapping转Punycode,本地部分不可转;最终取舍取决于业务规则而非正则本身。
用 Regex.IsMatch 判断邮箱格式是否合法
最直接的办法是调用 regex.ismatch,传入标准邮箱正则。但别抄网上那些“看起来很全”的长正则——它们要么漏掉合法邮箱(比如带 +tag 的 gmail),要么把明显非法的也放过(比如 @@example.com)。
推荐用这个平衡可读性与准确性的表达式:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
- 开头
[a-zA-Z0-9._%+-]+覆盖主流本地部分(含+和.,但不允许多个连续点) -
@后必须有域名和有效顶级域({2,}避免匹配user@a.b这种明显错的) - 注意:它不验证 DNS 或 MX 记录,只做语法检查 —— 这是合理预期
- 如果项目要求更严格(如禁止
.co.uk二级域名),得额外加逻辑,不能靠正则硬塞
为什么不用 MailAddress 构造函数做验证
有人会写 new MailAddress("test@domain.com") 看会不会抛异常。这方法看似“用 .NET 自己的逻辑”,实际问题很多:
- 它接受大量非 RFC 合规格式,比如
"John Doe" <john></john>或带空格的test @example.com(中间有空格) - 对某些边界输入反而抛
FormatException,但错误信息不明确,调试困难 - 构造对象有额外开销,纯校验场景没必要
- 真正要发邮件时再用
MailAddress解析更合理 —— 校验和使用职责分离
处理空字符串、null 和空白字符的坑
用户输入常是空或全是空格,而 Regex.IsMatch("", pattern) 返回 false,看似安全,但容易忽略前置/后置空格导致误判。
- 务必先调用
string.IsNullOrWhiteSpace(email)做快速拦截 - 不要用
Trim()后直接丢给正则 ——" user@domain.com "是合法的,但" user @ domain.com "(中间有空格)不是,Trim 无法修复后者 - 建议流程:判空 → Trim → 再正则匹配。顺序错了可能让
" @ "这种输入逃过空值检查 - 如果 UI 层已做 trim,后端仍要重复校验 —— 不信任任何外部输入
国际化邮箱(IDN)需要额外转码
遇到中文域名(如 张三@例子.中国)或带重音字母的邮箱,原始正则会失败,因为 DNS 只认 ASCII。
- .NET 提供
IdnMapping类,需先把域名部分转成 Punycode:idn.GetAscii("例子.中国")→"xn--fsq.xn--fiqs8s" - 不能整个邮箱一起转 —— 本地部分(@前)通常不支持 IDN,转了反而错
- 实际中,多数系统仍以 ASCII 邮箱为主,若业务明确不需要 IDN,跳过这步更省事
- 转码失败会抛异常,记得 try/catch,别让一个邮箱崩掉整个校验流程
真正难的不是写对正则,而是想清楚你要拦住什么、允许什么。比如要不要支持 test+newsletter@gmail.com?要不要拒绝 admin@localhost?这些得看业务规则,不是正则能自动决定的。


















