上次列举了正则表达式中的元字符,本文主要是是通过实例来尽可能多的介绍元字符的作用,所以会讲得比较罗嗦。如果你只是想要结果,请直接翻到最后。
用正则表达式来验证邮箱
平时在编程的时候,难免会对各种各样的字符串进行验证,比较多的就是对邮箱的验证。
以前见过通过是否含有@
来判断的,真的是太low了。
现在我们考虑用正则来判断邮箱地址是否有效。
最简单版本
首先邮箱地址中含有@
字符,并且有且仅有一个,这是一个普通字符,直接用它本身去匹配就行。然后左边和右边都要有字符,可以用通配符.
来匹配任意字符,但是.
只能匹配一次,需要能匹配多次,那么*
就出场了,*
表示匹配任意次,可以是0次。
似乎我们可以用.*@.*
来匹配邮箱地址了。但是注意到,aaa@
和 @aaa
也会被匹配到,可它们并不是有效的邮箱地址。还记得+
吗?它和*
差不多,但是匹配次数要求是至少一次。.+@.+
这样看起来是不是准一点了。
然而,又想到邮箱地址后缀是一个域名形式,必须是以.com
、.cn
等等形式结尾,也就是说右边至少是aaa.bbb
形式,怎么匹配呢,相信你应该能想到吧?对的,就是.*\..*
。
注意一下,.
表示匹配任意字符,如果想要表示.
这个普通字符,需要转义,转义的方式在前面加上\
,并且只能转义后面一个字符。再回顾一下吧,如果\
接的是元字符,那么就转义,如果是普通字符,还是作为普通字符来处理,也就是说,\
后面一定是作为普通字符来处理的。那么如何表示普通字符\
呢?很简单啦,\\
。
支持子域名
回到邮箱地址上来,我们现在得到的形式是.*@.*\..*
,似乎差不多了,但是[email protected]
这个有效的邮箱地址却不能正确的匹配。如果邮箱右边不是顶级域名,怎么解决呢?
想起来+
了吗,可以匹配至少一次的。但是.
和*
都是只能匹配前面最接近的,好像还是无法解决。这时候()
出场了,括号内的内容表示是一个分组,括号后面紧跟的元字符对分组作用。看起来我们可以用.+(\..*)+
来匹配右边,这样我的邮箱也可以匹配上了。
现在整个的正则表达式是这样的:.+@.+(\..*)+
,现在,我们已经可以匹配所有有效邮箱了。只是newnius.cn@@[email protected]
这种奇怪的字符串也能匹配上。知道怎么造成的吗?
限制仅有一个@
是的,.
能匹配任意字符。那如果想匹配特定字符怎么做?字符组。记得[ ]
吧,中括号内的字符表示匹配其中之一即可,好那把.
改成[-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]
,可以实现效果了,但是好长啊!可以用-
来简化的,比如说[123456789]
可以表示成[0-9]
,是不是很简洁?依葫芦画瓢,可以将长长的一串变成[-0-9a-zA-Z]
,注意,-
要放在最前面,否则会被理解成特殊字符的,当然,你也可以转义之后放在任意地方。
就快完成啦,现在我们得到了[-0-9a-zA-Z]+@ [-0-9a-zA-Z]+(\. [-0-9a-zA-Z]+)+
这样的正则表达式。(邮箱用户名不能以-
开头,这个我们一会再解决)
这样就可以匹配所有有效邮箱了,但是可以更好一点。还记得^
和$
吧,它们表示行开始和结束,如果是从表单中获取的数据可以用^[-0-9a-zA-Z]+@ [-0-9a-zA-Z]+(\.[-0-9a-zA-Z]+)+$
来进一步限制。如果是在一堆字符串里,可以用/<
,/>
这两个表示单词开始和结束的元字符表示。/<[-0-9a-zA-Z]+@[-0-9a-zA-Z]+(\.[-0-9a-zA-Z]+)+/>
。
不能以减号开头
差不多了啊,这样基本可以直接用了。有点小瑕疵,我们再精益求精一下,解决邮箱开始和域名开始不能是-
,那就分成第一个字符和不是第一个字符呗。结果如下:
1 | ^[0-9a-zA-Z][-0-9a-zA-Z]*@[0-9a-zA-Z][-0-9a-zA-Z]*(\.[-0-9a-zA-Z]+)+$ |
基本完成啦,这样可以是很精确了。尽管有更加精确的:限制邮箱域名后缀,但是目前顶级域名后缀太多啦,实在是列举不完,不过要是想限制只能哪一类邮箱,这倒是一个很好的方法。
以下是正则表达式在javascript中的具体使用。
1 | //正则判断邮箱 |
说明:
- 一些语言中“@”需要转义
- 一些语言中正则开始和结尾需要“/”
总结
回顾一下,这次我们通过“邮箱地址验证”实例学习了.
、+
、*
、()
、[]
,-
、^
、$
、\
这些元字符或者特殊字符的用法。
最后是本次得出的正则表达式:
1 | /^[0-9a-zA-Z][-0-9a-zA-Z]*@[0-9a-zA-Z][-0-9a-zA-Z]*(\.[-0-9a-zA-Z]+)+$/ |