js 邮箱正则表达式是前端做邮箱格式校验最常用的方案,核心作用是在用户输入邮箱的时候,提前判断字符串是否符合邮箱通用书写规范,减少无效请求发送到后端,提升交互体验,同时降低服务端校验压力。选择正则的时候要明白一个关键点,正则只能校验格式合法性,没办法验证这个邮箱真实存在,也不能确认邮箱账号可以正常收发邮件,这一点是所有邮箱正则的共性局限。邮箱标准结构是本地账号加 @符号再加域名,本地账号可以包含字母数字还有部分特殊字符,域名由多级子域名加顶级域名组成,域名部分不能以特殊字符开头结尾,还要符合域名命名规则。很多新手容易写过度严格或者过度宽松的正则,过度严格会拦截合规邮箱,过度宽松又会放过明显错误的输入,所以要根据业务场景选择适配版本。
基础通用版本
这个版本适合绝大多数普通业务项目,兼容主流邮箱写法,容错适中,也是网上使用最多的版本
const emailReg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
校验调用写法
function checkEmail(email) {
const reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
return reg.test(email)
}
字符含义拆解表格
| 正则片段 | 说明 |
|---|---|
| ^ | 匹配字符串开头 |
| [a-zA-Z0-9._%+-]+ | @前面本地账号,允许大小写字母数字 点 下划线 百分号 加号 减号,至少一位 |
| @ | 必须存在的邮箱分隔符 |
| [a-zA-Z0-9.-]+ | @后面域名主体,允许字母数字点短横线 |
| . | 匹配域名里必须存在的点号,用来分隔域名和顶级域 |
| [a-zA-Z]{2,} | 顶级域名,至少两个字母,比如 com cn org |
| $ | 匹配字符串结尾,防止后面追加多余字符 |
增强严格版本
如果业务需要更严谨的校验,可以增加限制,禁止本地账号开头结尾是点,不允许连续多个点,适合注册这类高要求场景
const strictEmailReg = /^[a-zA-Z0-9]([a-zA-Z0-9._%+-][a-zA-Z0-9])?@[a-zA-Z0-9]([a-zA-Z0-9-][a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-][a-zA-Z0-9])?)+$/
这个版本解决基础版本的缺陷,基础版本会允许 .abc@xxx.com 这种开头带点的邮箱通过校验,增强版本就会拦截这类不符合规范的写法。
注意事项
1 正则区分大小写的问题,默认正则可以同时识别大小写字母,如果业务不区分大小写,可以加上 i 修饰符,写法就是 /xxxx/i
2 顶级域名现在有很多新后缀,比如 xyz shop club,基础版本 {2,} 可以兼容,但是如果遇到国际化中文域名邮箱,普通 js 邮箱正则表达式是无法识别的,这种场景需要额外处理 punycode 转换
3 test 方法会受全局修饰符 g 影响,如果正则加了 g,多次调用 test 会出现 lastIndex 偏移,出现一次 true 一次 false 的诡异 bug,邮箱校验一般不要加 g
4 前端校验只是第一道防线,后端必须再次做邮箱校验,不能完全依赖 js 邮箱正则表达式,因为前端代码可以被篡改绕过
完整封装示例
const emailReg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
function validateEmail(inputValue) {
if(typeof inputValue !== 'string') {
return false
}
const value = inputValue.trim()
return emailReg.test(value)
}
这里增加 trim 是为了去掉用户输入前后不小心带入的空格,很多 bug 就是用户输入邮箱前后带空格导致校验失败。
【常见问题】
问题 1 js 邮箱正则表达式加上 g 修饰符为什么校验结果不稳定
回答 1 js 邮箱正则表达式带 g 全局标记的时候,test 方法会保存 lastIndex 索引,连续多次执行校验会从上一次的位置继续匹配,就会出现结果交替变化,邮箱校验场景不要使用 g 修饰符,只需要普通匹配即可。
问题 2 js 邮箱正则表达式能不能校验中文邮箱
回答 2 普通 js 邮箱正则表达式默认只识别英文字符,原生不能直接校验中文域名邮箱,中文域名需要先转成 punycode 编码之后,再使用邮箱正则表达式进行匹配校验。
问题 3 js 邮箱正则表达式为什么不能验证邮箱是否真实有效
回答 3 js 邮箱正则表达式只做字符串格式匹配,它没有联网查询邮箱服务器的能力,只能判断书写格式是否符合规则,无法确认这个邮箱账号是否注册存在,想要确认真实可用需要发送验证邮件。
问题 4 js 邮箱正则表达式顶级域名写 {2,} 是否足够
回答 4 大多数场景足够,{2,} 代表顶级域名最少两个字符,可以兼容 com cn net 等主流后缀,如果业务有特殊短后缀需求,可以按需调整这个数字限制。
【免责申明】
本文提供的 js 邮箱正则表达式仅作为前端格式校验参考,不同业务标准和邮箱协议存在差异,正则无法覆盖全部极端合法邮箱格式,生产项目请结合自身业务测试验证,使用产生的相关风险由使用者自行承担。


