《精通正则表达式》笔记 --- “验证”Email格式
写一个正则表达式的三个步骤:
- 理解需求并找出你需要验证的数据的特征;
- 写一个还可以用的正则表达式;
- 看看能不能达到你的目的,同时想想会不会匹配到一些不想要的数据;
- [可选]性能优化
我觉得写一个正则表达式可以简单的分为这么几个步骤。
好了,现在要验证一个电子邮件的地址的合法性。
首先,一般我们会在一些注册的时候验证用户输入的邮箱是否合法,但是我们在这一步能够做的验证其实是很少很少的,因为我们只能够保证用户输入的是一个合法的邮箱。但是我们没办法保证输入的是一个有效的邮箱,唯一验证邮箱是否有效的方法就是发送一个验证的邮件。
好了,既然了解到这一点,那么我们正则表达式就不需要100%准确的去验证邮箱的合法性,只需要把一些看上去错的离谱的去除掉就可以了。再次之前让我们看一个根据Email标准(RFC 5322)写出来的能够验证出所有有效邮箱地址的表达式:
(?:(?: )?[ ])*(?:(?:(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ] )+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:( ?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*))*@(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)* ](?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+ (?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?: (?: )?[ ])*))*|(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+| |(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: ) ?[ ])*)*<(?:(?: )?[ ])*(?:@(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: r )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: ) ?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ] )*))*(?:,@(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])* )(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ] )+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*) *:(?:(?: )?[ ])*)?(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+ ||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*))*@(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31 ]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*]( ?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(? :(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(? : )?[ ])*))*>(?:(?: )?[ ])*)|(?:[^()<>@,;:\".[] 00- 31]+(?:(? :(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )? [ ]))*"(?:(?: )?[ ])*)*:(?:(?: )?[ ])*(?:(?:(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]| \.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<> @,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|" (?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*))*@(?:(?: )?[ ] )*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\ ".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(? :[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[ ]]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*|(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\.|( ?:(?: )?[ ]))*"(?:(?: )?[ ])*)*<(?:(?: )?[ ])*(?:@(?:[^()<>@,; :\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([ ^[] \]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\" .[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[ ] \]|\.)*](?:(?: )?[ ])*))*(?:,@(?:(?: )?[ ])*(?:[^()<>@,;:\". [] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] r\]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \] |\.)*](?:(?: )?[ ])*))*)*:(?:(?: )?[ ])*)?(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(?:[^" \]|\ .|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@, ;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|"(? :[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*))*@(?:(?: )?[ ])* (?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\". []]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[ ^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[] ]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*>(?:(?: )?[ ])*)(?:,s*( ?:(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\ ".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)(?:.(?:( ?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[ ["()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*))*@(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(? :.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+| |(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*|(?: [^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\".[ ]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)*<(?:(?: ) ?[ ])*(?:@(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[[" ()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: ) ?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<> @,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*(?:,@(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@, ;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(?:.(?:(?: )?[ ] )*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\ ".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*)*:(?:(?: )?[ ])*)? (?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[["()<>@,;:\". []]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ])*)(?:.(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+||(?=[[ "()<>@,;:\".[]]))|"(?:[^" \]|\.|(?:(?: )?[ ]))*"(?:(?: )?[ ]) *))*@(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ]) +||(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*)(?: .(?:(?: )?[ ])*(?:[^()<>@,;:\".[] 00- 31]+(?:(?:(?: )?[ ])+| |(?=[["()<>@,;:\".[]]))|[([^[] \]|\.)*](?:(?: )?[ ])*))*>(?:( ?: )?[ ])*))*)?;s*)
好吧,我们看看就好。下面这个才是平时我们可以用到的。
[-a-zA-Z0-9_+]+(?:.[-a-zA-Z0-9_+]+)*@(?:[-a-zA-Z0-9]+.)+[a-zA-Z]{2,6}
[-a-zA-Z0-9_+]+
表示@号之前可以包含所有的字母,数字,加减号和下划线。后面的(?:.[-a-zA-Z0-9_+]+)*
唯一的区别就是前面有一个点,这个表达式的意思是说可以有若干个以.
分割的一组字母,主要为了避免像这种情况 --- a....@msn.com
。
@
后面则是验证域名部分的,(?:[-a-zA-Z0-9]+.)+
是匹配1个或多个域名前面的部分,之所以要多个是因为有一些域名由多部分组成或者是邮箱是子域名下的邮箱。最后[a-zA-Z]{2,6}
则匹配的就是顶级域名部分,因为大部分域名的长度都在2到6为所以这里限制了长度为2-6。
关键的概念
- 非捕获型括号
- 量词