最稳妥的正则表达式是^[a-zA-Z0-9.\_%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$,它允许本地部分含点、下划线、+和-,拒绝连续点及user@a.b类错误,支持Gmail的+tag但不处理IDN或RFC复杂格式。

直接用 Regex.IsMatch 配合合理正则表达式是最可靠、最可控的方式;别用 MailAddress 构造函数“碰运气”,也别抄网上动辄几百字符的“全能正则”——它们要么漏合法格式(如 user+tag@gmail.com),要么放过明显非法输入(如 @@example.com)。
用哪个正则模式最稳妥?
推荐这个兼顾可读性、覆盖主流场景且避免常见陷阱的表达式:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
- 开头
[a-zA-Z0-9._%+-]+允许本地部分含点、下划线、+和-,但不允许多个连续点(如user..name@example.com会被拒) - @ 后必须有域名 + 有效顶级域,
{2,}防止匹配user@a.b这类明显错误 - 它不支持 IDN(如中文域名),也不处理带引号或注释的 RFC 复杂格式——这些本就不该在注册/登录环节强求
- 若需支持
+tag(Gmail 常见),该正则已包含+;若业务禁止+,删掉即可
为什么不能用 new MailAddress() 做校验?
看似“用 .NET 自己的逻辑”,实际问题明确:
-
new MailAddress(" test @ example.com ")不抛异常(中间空格被容忍),但真实邮箱系统通常拒绝 -
new MailAddress("John Doe <john>")</john>也能构造成功,这根本不是纯邮箱地址,而是带显示名的完整邮件头格式 - 对某些边界输入(如缺失
@或双@)抛FormatException,但错误信息是泛化的,无法定位具体哪部分错 - 每次调用都新建对象,有 GC 开销;纯格式校验没必要走这一层
真正要用 MailAddress 的地方,是发邮件前解析收件人列表,而不是前端输入拦截。
空值、空格和 IDN 怎么处理?
这三个点最容易漏,一漏就线上出问题:
- 先调
string.IsNullOrWhiteSpace(email)快速返回false,别等正则去匹配空串 - 再做
email.Trim(),但仅用于清除首尾空白;"user @ domain.com"中间空格仍非法,Trim 不会修复,正则本身也不该匹配它 - 遇到中文域名(如
user@例子.中国),必须拆出域名部分,用IdnMapping.GetAscii("例子.中国")转成xn--fsq.xn--fiqs8s,再拼回完整邮箱参与正则匹配;本地部分(@前)绝不能转 Punycode
IDN 处理不是可选项——2026 年国内政务、教育类系统已强制要求支持中文域名邮箱,但多数开发者还在用原始正则硬扛,结果就是用户输对了却提示“格式错误”。


















