Regular Expression – (正则表达式)匹配 Email 地址

在开发中我们经常会碰到用正则表达式匹配电子邮件地址的任务,今天就来讲讲如何用正则表达式匹配电子邮件地址。不过今天我打算换一个思路来说明正则表达式如何匹配 E-mail 地址,今天我首先会给出答案,然后教大家如何解读一个正则表达式。

先来看看我给出的匹配 E-mail 地址 的表达式吧:

// 使用 JavaScript 语言的语法
var regEmail = /^[a-z0-9]+[_.]?[a-z0-9]+@[a-z0-9]+([-]?[a-z0-9]+)*\.[a-z]{2,6}(\.[a-z]{2})?$/i; 

这么一长串表达式,是不是不知道如何下手来阅读啊?不要紧张,我会把它分解成不同的片段逐个解释的。首先,我们还是看看合法的电子邮件地址是怎样的:

yaohaixiao@email.com
haixiao_yao@email.com
haixiao.yao@email.com
yaohaixiao82@email.com.cn

可以看到,电子邮件地址的格式是这样的:用户名@服务器域名地址。由于中间的“@”分隔符是固定的,实际上我们要用正则表达式处理的只有用户名和服务器域名地址两个部分。

再看看我给出的表达式,找到@符号。那么@符号前面的([a-z0-9]+[_.]?[a-z0-9]+)就是用户名的匹配规则,@符号后面的([a-z0-9]+([-]?[a-z0-9]+)*\.[a-z]{2,6}(\.[a-z]{2})?)就是服务器域名地址的匹配规则。

大小写问题

在介绍具体的匹配规则前,首先要介绍的是正则表达式关于大小写区分的表示方法。在(JavaScript版本的)表达式中,最后的i,表示前面的匹配规则(英文字母)都不区分大小写。

位置匹配

除了前面分离出来的匹配用户名和匹配域名的规则外,在表达式开头和结尾还有两个特殊的符号:^$

在正则表达式中 ^ 是用来表示字符串开始位置的元字符,而 $ 是用来表示字符串结束位置的元字符。

用户名的匹配规则中的 ^[a-z0-9]+,表示的就是用户名以数字或字母开始,而数字和字母的重复匹配次数至少为1次。换作通俗的话解释(规则)就是:用户名必须以字母或数字开头,字符长度至少为1(当然,用户名还有其他规则,字符长度实际上会不只1个字符串)。

而服务器域名地址的匹配规则中的\.[a-z]{2,6}(\.[a-z]{2})?$,要比开始位置更复杂。

首先看这段表达式(\.[a-z]{2})?,”()”(括号)表示这是一个子表达式(表示例如:.cn 这样的国家或地区域名后缀),而?,则表示这个子表达式重复匹配的次数是0-1次。也就是说(\.[a-z]{2})?$,表示的意思是 Email 地址的域名部分可能以国家或地区域名后缀结尾。也有可能以[a-z]{2,6}(标准的域名后缀)结尾。举个例子说,.com 或者 .com.cn 这样域名后缀结尾都是合法的。

用户名的匹配规则

简单的介绍了正则表达式的位置匹配后,接着就是介绍用户名的匹配规则的表达式:

[a-z0-9]+[_.]?[a-z0-9]+

这段表达式可以分解成3部分:[a-z0-9]+[_.]?[a-z0-9]+。都是由个字符集合区间连接重复匹配元字符的形式组成,意思就是字符集合中的字符会重复几次。

[a-z0-9]+这段表达式已经在前面解释过了,就不重复了。来看看 [_.]?,它表示下划线(_)或者点(.)会重复0-1次(?代表重复0-1次)。换作通俗的话就是下划线(_)或者点(.)是可选的,这两个字符任意的一个可能会出现1次(也可能不出现)。

最后一段表达式也是[a-z0-9]+,意思是在可能出现的下划线(_)或者点(.)后,紧接会至少出现1个字母或者数字。

这样以来^[a-z0-9]+一开始会出现至少1个数字或者字母,[_.]?可能会出现下划线(_)或者点(.),接着[a-z0-9]+又至少出现1次数字或者字母。那么,用户名就最少有2个字符长度(基本就是两个字的中文名的首拼英)。

^[a-z0-9]+[_.]?[a-z0-9]+ 完整的意思就是用户名必须以数字或字母开头,字符长度至少为1,后面可以用下划线或者点连接,然后又必须连接的是数字和字母,字符长度至少为1。而用户名总的字符数至少为2个字符。

// 合法的用户名
11
robert
rober.yao
robert_yao
1_1
a.a

// 不合法的用户名
1(字符长度小于2)
a(字符长度小于2)
robert.(.后没有字符)
robert._(.和_只会出现一个,并且最多只会出现1次,不会同时出现)
.robert(必须以字母或数字开头)
_12(.必须以字母或数字开头)

服务器域名地址的匹配规则

服务器域名地址其实也可以细分一下,它的格式是:域名名称+域名后缀。来看看匹配域名地址的表达式吧:

[a-z0-9]+([-]?[a-z0-9]+)*\.[a-z]{2,6}(\.[a-z]{2})?

匹配域名名称

[a-z0-9]+([-]?[a-z0-9]+)* 这一小段表达式就是匹配域名名称的规则。[a-z0-9]+表示域名名称必须是以数字和字母开头的,且至少有1个字符(+表示至少出现一次)。

([-]?[a-z0-9]+)* 这段代码就复杂一些了,首先看这段代码使用了子表达式(括号),紧接着重复匹配的元字符“*”,表示这个自表达式的内容重复任意次数,也就是子表达式的内容是可选的,能不出现,也可能出现多次。再来看子表达式的内容[-]?[a-z0-9]+[-]? 表示连接符(-)重复匹配0-1次,也就是说连接符是可选的,可能会出现1次。而后面紧接的[a-z0-9]+则表示连接符如果出现,后面一定会有至少1个字符(数字或字母)出现。

最后完整的解释一下 [a-z0-9]+([-]?[a-z0-9]+)* 这段表达式的含义。它表示域名的名称必须以数字和字母开始,至少有1个字符。名称中可能会有连接符+字符的形式(例如:-a),而且只要出现连接符,后面就一定会有数字或者字母出现。

// 合法的域名名称
1(单个字母或数字的域名应该都相当值钱了)
yaohaixiao
58
51job
font-end
font-end-end-end-end-end

// 非法的域名名称
58-(连接符后必须有字母或数字,不能以连接符结束)
-yao(必须以数字或者字符开头)

匹配域名后缀

\.[a-z]{2,6}(\.[a-z]{2})? 这段表达式就是匹配域名后缀的规则。\.[a-z]{2,6}匹配普通的后缀的规则:点+(2-6个)字母(例如:.cn .com .net .tv .online 等等)。(\.[a-z]{2})?匹配的可选的国家和地区(标准的iso国家地区缩写都是2个英文字母)的域名后缀。\.[a-z]{2,6}(\.[a-z]{2})?$完整的意义也在前面解释过了,就不重复了。

[a-z0-9]+([-]?[a-z0-9]+)*\.[a-z]{2,6}(\.[a-z]{2})? 完整的意思是域名地址必须以数字或者字母开头,字符长度至少为1,可以出现连接符+数字字母的形式,且出现连接符就一定会出现数字和字母(至少1个字符长度),不能以连接符结束(必须以数字或者字母结束)。域名后一定会有一个域名后缀,可以是.com形式,也可以是.com.cn这种普通后缀+国家地区后缀的形式。

总结

不知道这么解释如何用正则表达式匹配 Email 地址大家是否能理解。其实看上去十分难懂的正则表达式都是可以划分成若干个小段去分析的,而这些小段的表达式基本都是由位置匹配,字符集合区间,重复匹配以及子表达式进行各种组合而成的。

这次就讲到这里,下次会分析用正则表达式匹配 HTML 标记,会涉及正则表达式的另外两个重要的知识点:回溯引用和前后查找。

SHARE THIS PAGE

免责声明:本站文章中的观点都是作者个人观点,并没有以任何方式反映他所属机构的意见。

发表评论