曾经,我非常羡慕那些人见人爱的人,我也想要变成那样,可是后来我才明白人见人爱也是需要天赋的,后来我开始默默努力,我想,就算我不能让每个人都喜欢我,至少因为我做的努力能得到别人的尊重。

正则表达式之字符串验证

正则表达式之字符串验证

  在博文《正则表达式之数字验证》中我们探讨了数字的验证,比如身份证号码的验证、电话号码的验证等等,这些都是非常有用的;然而字符串的验证也是非常重要的。这篇博文我将和大家分享字符串的验证方法,如英文单词的验证、非单词字符串的验证、文件名称的验证以及网络常用元素的验证等等。 由于水平有限,有些知识点可能理解的不一定准确,希望如果大家发现错误后可以提出,在此表示感谢。

  

第一部分:5种英文单词验证

1.小写英文单词的验证

  • 我们可以使用[a-z]+验证一个或多个小写英文单词,当然[a-z]{1,}亦是如此。但是这样验证的单词可能不是完整的,如对于字符串ad“”,它将匹配其中的ad。
  • 为了解决上一个问题--即不能验证完整的单词,我们可以使用\b[a-z]+\b来验证。即通过元字符\b来指定英文单词的边界。
  • \ba[a-z]*\b 可以验证以小写字母a开头的一到多个英文字母的单词。(注:限定符*表示0个或多个)
  • \b[a-c][a-z]*\b可以验证以小写字母a或b或c开头的一个到多个英文字母的单词。
  • \b[a-z]+(?:ing)\b 可以匹配以ing结尾的字符串
  • \b[a-z]{6} 可以验证长度为6的小写英文组成的字符串

     注意:倒数第二个验证中的(?:ing), 虽然这里使用了(),即分组符号,但实际因为有?:,我们是不能进行反向引用的。 这里可以理解为我们仅需要将之看作一个整体,但是不希望被反向引用。

 

2.大写英文单词的验证

  这里与小写英文单词的用法相同,我们只需要将上面的[a-z]替换成[A-Z]即可。

 

3.英文单词的分隔符验证

  在英文文本中,各个英文单词被分隔符所分开。 分隔符即分开两两英文单词的符号。这些分隔符包括英文标点符号,空白符等等。

  在分隔符中,又以英文标点符号居多,比如,(逗号) .(点号) ?(问号) :(冒号) ;(分号) '(单引号) !(感叹号) "(双引号) -(连接号) --(破折号) ()(小括号) [](中括号) {}(大括号)  ...(省略号) `(所有格符号,又称反引号)。

  如下面的正则表达式将验证这些英文标点符号分隔符:

[-,.?:;'"!`]|(-{2})|(\.{3})|(\(\))|(\[\])|({})

 

     我为什么没有把所有的英文分隔符都放到字符类【】中去呢?这是因为对于--(破折号)...(省略号) ()(小括号)   [](中括号) {}(大括号)这些分隔符或者会引起歧义不能正确表达出来,或者必须使用\来转义。

 

4.否定验证

  • \b[A-GI-Z]+\b可以验证任何没有字母H的英文单词
  • \b[A-GI-OQ-Z]\b可以验证任何没有字母H和P的英文单词
  • \b[A-Z]*B[^P][A-Z]*\b可以验证任何在B之后没有P的英文单词。
  • 但是为什么DAFB没有被匹配上呢?这是因为在B之后[^P]占了一个位置,即最后一定不能什么都没有。

 

5.具有相同特征的英文单词验证

  a、使用\b([A-Z])\1[A-Z]*\b可以验证具有两个相同字母开头特征的英文单词。因为\1是在反向引用第一个分组。

  b、使用\b([A-Z])[A-Z]*\1+[A-Z]*\b可以验证具有一个和首字母相同的字母特征的英文单词。

  举例如下所示:

 

 

第二部分:6种非单词字符的验证

  这一部分将介绍非单词字符串的验证,比如英文标点符号、中文标点符号、中文文本验证、特殊字符验证和密码验证。

1.英文标点符号的验证

  即如下所示,在上面我们已经见过了:

[-,.?:;'"!`]|(-{2})|(\.{3})|(\(\))|(\[\])|({})

 

2.中文标点符号验证

  中文标点符号也很多并且和英文标点符号很类似。如 ,(逗号) 。(句号) ?(问号) :(冒号) ;(分号) ‘’(单引号) !(感叹号)  “”(双引号)  —(连接号)  ——(破折号)  ……(省略号)  ()(小括号)  【】(中括号)  {}(大括号)  、(顿号)  《》(书名号) 等等。

  于是我们可以通过下面的正则表达式来验证:

[,。?:;“” ‘’ !— …… 、]|(—{2})|(())|(【】)|({})|(《》)

其中(—{2})用来匹配破折号

 

3.中文文本验证

  中文文本的验证比较简单,我们直接使用/w即可实现。如下图所示:

    

  需要注意的是,如果没有u(注意观察灰色部分),则不能正确匹配,在http://www.regexpal.com/中我打开了unicode之后才可以正常匹配。

 

 

 

4.特殊字符验证  

  我们认为除了数字和字母之外的字符都是特殊字符,具体包括 、_ = \ [ ] ; ' ,. / ~ ! @ # $ % ^ & * ( ) + | ? > < “ :{ }。

  使用以下正则表达式即可验证一个特殊字符:

 [、_ =\ \\ [\ ] ; ' ,. / ~ ! @ # $ % ^ & * ( ) + | ? > < “ :{}]

  其中\ [ ]需要通过使用\进行转义。

  当然,如果需要验证长度至少为1、由特殊字符串组成的字符串,可直接在上面的正则表达式右边添加+即可。

 

5.密码验证

  当用户登陆网站时,一般都需要用户输入用户名和密码,这时作为前端攻城狮的我们就需要进行验证了。当然,一般来说,密码的复杂程度越高,用户信息安全性越高。

  密码字符可以包括数字、字母和特殊字符。因此在一个密码中可以只有数字或只有字母或只有特殊字符,也可以同时拥有其中的两种,或同时拥有其中的三种,显然,拥有的种类越多,则改密码越安全。

A 只包含数字的密码验证

  这种形式的验证显然是非常简单的,其安全性也非常低。如下所示:

\d+

  这样的表达式可以验证数字个数大于等于1的密码。而一般我们输入密码时有具体的要求,比如6到12位,我们可以按照下面的方式来验证。

\d{6,12}

  

B 只包含字母的密码验证

  这也很简单,同样安全性较差。我们可以这样验证限制在6-12位的密码。

 

C 只包含特殊字符的密码验证

  同样很简单,即

 [、_=\\\[\];`',./~!@#$%^&*()+|?><":{}]{6,12}

  此正则表达式验证的是6到12位的纯特殊字符的密码。

 

D 包含数字和字母的密码验证

  这里似乎很简单,但实际上却不是,因为我们必须保证数字和字母同时都有。我的思考如下(如果大家觉得有更简洁的方式可以提出来):

[\da-zA-Z]*((\d+[a-zA-Z]+)|([a-zA-Z]+\d+))[\da-zA-Z]*

  其中中间的分组(第一个分组)((\d+[a-zA-Z]+)|([a-zA-Z]+\d+))表示这个密码中必须是一个或几个数字后面跟着一个或几个字母 或者 一个或几个字母后面跟着一个或几个数字。如45dda或da564这种形式,如果一个密码时555或daf这肯定是不能匹配的。但这还是不够的,如果我们还希望在45dda的左边有字母,右边还有数字时,我们就需要在两边添加[\da-zA-Z]*了,其中*表示0个或多个。

 

E 包含数字和特殊字符的密码验证

  在D的基础上,这里的正则表达式就很好写了,只需将字母的验证替换为特殊字符的验证即可,如下所示:

[\d、_=\\\[\];`',./~!@#$%^&*()+|?><":{}]*((\d+[、_=\\\[\];`',./~!@#$%^&*()+|?><":{}]+)|([、_=\\\[\];`',./~!@#$%^&*()+|?><":{}]+\d+))[\d、_=\\\[\];`',./~!@#$%^&*()+|?><":{}]*

 

F 包含字母和特殊字符的密码验证

  在E的基础上,我们直接将其中的数字用字母来替换即可,如下所示:

[a-zA-Z_=\\\[\];`',./~!@#$%^&*()+|?><":{}]*(((a-zA-Z)+[_=\\\[\];`',./~!@#$%^&*()+|?><":{}]+)|([_=\\\[\];`',./~!@#$%^&*()+|?><":{}]+(a-zA-Z)+))[a-zA-Z_=\\\[\];`',./~!@#$%^&*()+|?><":{}]*

  这里为什么验证不成功呢??  如果有大神了解,希望可以给予指导,感激。

 

G 包含字母、数字和特殊字符的密码验证

  如果三者都包含,那么此时密码的安全度是最高的。那么,怎么实现这样的密码验证呢?

  思路同样的,即左右两边需要有字母、数字、字符串同时放在一个字符类里,中间的分组需要通过6次或运算即可实现。

  

  

第三部分:文件名称验证

   每一个文件都有它自己的名称,该名称由两部分组成:文件名和文件扩展名。基于此,下面我们将要介绍 指定文件扩展名的验证、 指定文件名的验证、 包含指定字符串的文件全名的验证、 排除两端存在空白符的文件全名验证。

1. 指定文件扩展名的验证 

  假设我们验证文件扩展名为pdf的名称。验证时,文件名是长度至少为1的任意字符串。方法如下:

      

  其中.+表示匹配长度至少为1、由非换行符组成的字符串。\.是为了对.进行转义。

2. 指定文件名的验证

  假设我们验证文件名为javascript的名称。验证时,文件扩展名是长度至少为1的单词字符串。方法如下:

      

 

3. 包含指定字符串的文件全民名验证

  这种验证方法是非常常见的,即一个文件全名中需要包含指定的字符串,比如一个文件全民中必须包含java这个字符串。验证方法如下:

  

 

4. 排除两端存在空白字符的文件全名验证

  前面我们没有考虑到文件名两端存在空白字符的情况,然而,文件名的两端是不允许存在空白字符的。 

   (1)如果验证一个字符串不是以空白字符开头,可用(?!expression),即零宽度负预测先行断言。该断言可以指定此位置的后面不能匹配表达式expression,于是验证如下:

    

   (2) 如果验证一个字符串不是以空白字符结束,可用(?<!expression),即零宽度负回顾后发断言,它断言自身位置的前面不能匹配表达式expression,于是验证如下:

^.+(?<! )\.\w+$

 

(3) 结合上面两种情况,即可得到文件名两端都不存在空格的验证如下所示:

^(?! ).+(?<! )\.\w+$

 

 

第四部分:电子邮件、HTTP/FTP地址验证

  这四个都是网络的常用元素,尤其是电子邮件的验证用的很多。

1.电子邮件验证

   我们知道常见的电子邮箱有163 邮箱 126 邮箱 QQ 邮箱 Gmail邮箱 雅虎邮箱 Hotmail 新浪邮箱 139 邮箱 TOM邮箱 21CN邮箱 搜狗邮箱 189邮箱 188财富邮亿邮 Yeah邮箱 搜狐邮箱 Foxmail等等,但是他们的特点都十分类似,如qq邮箱地址:1843021156@qq.com,Gmail邮箱地址 zhuzhenwei789@gmail.com等等。当然上述的邮箱是大型公司提供的免费邮箱。 公司还可以有自己的企业邮箱。比如123456abcd@facai.com.cn等等。

  综上所述,我们可以看出邮箱一般是由名称、字符@和域名后缀组成。

  根据邮箱的特点,我们便可以使用下面的正则表达式来验证电子邮件地址:

^\w+@(\w+\.)+\w+

  效果如下所示:

  当然,下面这种方法(思路)也是一样的:

^\w+@\w+(\.\w+)+

  上面的说法是有问题的,这里更正,应该是 

^[\w.]+@(\w+\.)+\w+

  因为前面的名称也有可能是有小数点的。

2.HTTP、FTP地址验证

   HTTP地址一般是以字符串"http://"或"https:"开头的字符串。它可以被. / ? & % =分割。 如http://www.cnblogs.com、https://www.baidu.com/s?wd=谷歌&rsv_spt=1、http://cn.bing.com/search?q=javascript等等。而FTP和HTTP的唯一区别在于开头是FTP而不是HTTP或HTTPS。

      于是可知验证表达式如下:

((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?

       首先该正则表达式匹配的字符串必须以http://、https://、ftp://开头;

       其次该正则表达式能匹配URL或者IP地址;(如:http://www.baidu.com 或者 http://192.168.1.1)

      然后该正则表达式能匹配到URL的末尾,即能匹配到子URL;(如能匹配:http://www.baidu.com/s?wd=a&rsv_spt=1&issp=1&rsv_bp=0&ie=utf-8&tn=baiduhome_pg&inputT=1236)

      最后该正则表达式能够匹配端口号;

 

 

结语:

  这篇文章写完才发现对正则表达式的理解还不够透彻,比如字母、数字、特殊字符构成的密码验证还有些问题待解决,最后HTTP和FTP的验证我觉得写的也过于繁杂,并没有解决所有问题。所以如果大家有什么好的建议希望可以指教,在此表示感谢。

 

 

注:原创文章,如需转载,请注明出处,博客地址:http://www.cnblogs.com/zhuzhenwei918/p/6202932.html

posted @ 2016-12-20 15:45  Wayne-Zhu  阅读(32435)  评论(0编辑  收藏

一分耕耘,一分收获。