正则表达式结合实例简单梳理

        正则表达式在所有语言中都是通用的,它使用一种特定的规则来匹配一个字符串,当满足这个规则,就认为此字符串匹配成功。结合各个语言中的不同方法,可以返回匹配成功true、false或者匹配的字符串等。

        本文对正则表达式做一个简单的知识梳理,结合一些小例子来加深印象。

        正则表达式的验证方法现在也多种多样,在这里就不推荐了,大家选择适合自己用得惯的就好。

 

常用元字符

        既然是特定的规则,那么在正则表达式中就有相对应的特殊符号,你不用去记它的名字是什么,只需要知道它做了什么。

.	匹配除换行符以外的任意字符
\w	匹配字母或数字或下划线或汉字
\s	匹配任意的空白符
\d	匹配数字
\b	匹配单词的开始或结束
^	匹配字符串的开始
$	匹配字符串的结束

  这里分辨一下\b与^、$的区别,\b匹配的是单词的开始或结束,也就是说它匹配的是一个“单词”,而^与$是匹配字符串的开始或结束。看下面的例子

        

        图中,用\b去匹配字符串的时候虽然设定的匹配条件是\w.*匹配任意数量的字母数字汉字或下划线,□□□abc虽然不是以匹配条件开头,但对于\b来说,a才是一个单词的开始。而^与$则是指定了必须要以匹配条件开头,所以□□□abc未能匹配。

        另外,对于单词界限通常认为是以空格,符号做分割。

        更多例子:

        \ba\w*\b匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)。

        ^\d\w*$匹配以1个数字开头,任意字母或数字结尾

常用反义字符

        与上述元字符所匹配的规则相反。这里的反义字符一般用于想匹配没有数字,或没有空白字符的情况,也就是限定条件唯一的情况下用比较方便(好吧,可能是我用这方面的功能比较多,其他功能大家可以自行去发掘~)

\W	匹配任意不是字母,数字,下划线,汉字的字符
\S	匹配任意不是空白符的字符
\D	匹配任意非数字的字符
\B	匹配不是单词开头或结束的位置
[^x]	匹配除了x以外的任意字符

        需要注意的是,\S匹配的并不是以空格分割的字符串,而是每个字符,也就是说匹配的是单个字符

        更多例子:

        \S+匹配不包含空白符的字符串。

        <a[^>]+>匹配用尖括号括起来的以a开头的字符串。

常用限定符

        个人理解限定符就相当于把原来的元字符从加法转换成了乘法。

*	重复零次或更多次
+	重复一次或更多次
?	重复零次或一次
{n}	重复n次
{n,}	重复n次或更多次
{n,m}	重复n到m次

        例如\d\d\d\d\d匹配五个数字现在就可以写成\d{5}。

        更多例子:

        abc\d+匹配abc后面跟1个或更多数字

        ^\w+匹配一行的第一个单词

分组

        重复单个字符很简单,那重复多个字符就需要用到分组了。分组就是在你需要重复的字符外加一个括号。这就像我们做四则运算时需要先算加法再算乘法的话,需要先把加法式子用括号括起来一样。

捕获
(exp) 匹配exp,并捕获文本到自动命名的组里 (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置 (?<=exp) 匹配exp后面的位置 (?!exp) 匹配后面跟的不是exp的位置 (?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

        在正则表达式中,用括号分组之后的匹配文本会被捕获到自动命名的组中,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。利用这个特点,我们可以给分组命名,这样就可以很方便地获得分组中的文本了。

        更多例子:

        \b(\w+)\b\s+\1\b匹配重复的文本。(括号中的文本被捕获成一个分组,后面\1又匹配了一次第一个分组中的文本)

        (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。

        (?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

其他小规则

|     分支
懒惰匹配
*?	重复任意次,但尽可能少重复
+?	重复1次或更多次,但尽可能少重复
??	重复0次或1次,但尽可能少重复
{n,m}?	重复n到m次,但尽可能少重复
{n,}?	重复n次以上,但尽可能少重复

        0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。分支的用法就相当于或,匹配 | 分割的任意一个规则

        需要注意的是,分支也有短路现象。

        当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。但我们有时候需要的是匹配尽可能短的字符,这个时候就需要用到懒惰匹配。

        a.*?b匹配最短的,以a开始,以b结束的字符串。当我们输入abbaab时,它会匹配ab和aab。

常用匹配规则

        以下整理自网络

匹配合法邮箱:
[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?
匹配网址URL:
[a-zA-z]+://[^\s]*
匹配18位身份证号码:
^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$
匹配合法年月日:
([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))

 

参考资料:

http://www.jb51.net/tools/zhengze.html

http://blog.sina.com.cn/s/blog_47664968010093q0.html

posted @ 2018-05-31 15:47  Chellyyy  阅读(335)  评论(0编辑  收藏  举报