《精通正则表达式》笔记 --- “验证”Email格式

写一个正则表达式的三个步骤:

  1. 理解需求并找出你需要验证的数据的特征;
  2. 写一个还可以用的正则表达式;
  3. 看看能不能达到你的目的,同时想想会不会匹配到一些不想要的数据;
  4. [可选]性能优化

我觉得写一个正则表达式可以简单的分为这么几个步骤。

好了,现在要验证一个电子邮件的地址的合法性。

首先,一般我们会在一些注册的时候验证用户输入的邮箱是否合法,但是我们在这一步能够做的验证其实是很少很少的,因为我们只能够保证用户输入的是一个合法的邮箱。但是我们没办法保证输入的是一个有效的邮箱,唯一验证邮箱是否有效的方法就是发送一个验证的邮件。

好了,既然了解到这一点,那么我们正则表达式就不需要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。

关键的概念

  1. 非捕获型括号
  2. 量词