代码改变世界

正则表达式总结

2016-10-11 16:05  半颗花生  阅读(324)  评论(0编辑  收藏  举报

正则表达式

一、热身

1、.是另一个元字符,匹配除了换行符以外的任意字符。

2、+匹配前面的子表达式一次或多次,+等价于{1,}

3、*同样是元字符,不过它代表的不是字符,也不是位置,而是数量
它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配

4、\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置

5、\d表示匹配一位数字(0、1、2...)

6、- 只匹配它本身

7、\s匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等。

8、\w匹配字母或数字或下划线或汉字等


二、元字符

1、\b\w{6}\b 匹配刚好6个字符的单词

2、. 匹配除换行符以外的任意字符

3、\w 匹配字母或数字或下划线或汉字

4、\s 匹配任意的空白符

5、\d 匹配数字

6、\b 匹配单词的开始或结束

7、^ 匹配字符串的开始

8、$ 匹配字符串的结束

9、元字符^(和数字6在同一个键位上的符号)和$都匹配一个位置,这和\b有点类似。
^匹配你要用来查找的字符串的开头,$匹配结尾。
这两个代码在验证输入的内容时非常有用,
比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$。

三、转义字符

1、如果你想查找元字符本身的话,比如你查找.或者*就出现了问题:你没办法指定它们,
因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。

因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.

例如:derchao\.net 匹配derchao.net ,C:\\Windows 匹配 C:\Windows

四、重复

常见用法:

1、* 重复零次或更多次
2、+ 重复一次或更多次
3、? 重复零次或一次
4、{n} 重复n次
5、{n,} 重复n次或更多次
6、{n,m} 重复n到m次


例如:
Windows\d+匹配Windows后面跟1个或更多数字

^\w+匹配一行的第一个单词(或整个字符串的第一个单词,具体匹配哪个意思得看选项设置)

五、字符类

1、要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集合的元字符,但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?

2、很简单,只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。

3、我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。


4、下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}。
“(”和“)”也是元字符,后面的分组节里会提到,所以在这里需要使用转义。
这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,
或02912345678等

5、我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,
后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),
最后是8个数字(\d{8})。

六、分枝条件

1、正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,
具体方法是用|把不同的规则分隔开


2、例如:

a、 0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字符分隔的电话号码,
一种是三为本地区号,一种是四位本地区号

b、 \(?0\d{2}\)?[ -]?\d{8}|0\d{2}[ -]?\d{8}这个表达式匹配三位区号,
其中区号可以用括号也可以不使用括号

c、 \(?0\d{3}\)?[ -]?\d{8}|0\d{3}[ -]?\d{8}这个表达式匹配四位区号

3、注意:

使用分枝条件时,要注意各个条件的顺序,执行顺序为从左到右

如:

\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码,美国的邮政编码是五位数字,
或者用连字号间隔的9位数字。如果改为\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的
邮编或者9位的前5位,原因是匹配分枝条件时,将会从左到右地测试每个条件,
如果满足了某个分枝的话,就不会再管其他条件了

七、分组

1、如果想要重复多个字符,可以用小括号来指定子表达式(也叫做分组)

2、简单的ip地址匹配

(\d{1,3}\.){3}\d{1,3} 是一个简单的ip地址匹配表达式,(\d{1,3}.)表示匹配1到3位数字
加一个英文点,{3}表示重复3次,\d{1,3}表示匹配1到3位数字

2、ip地址匹配

((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

此表达式比较严格的定义出了ip地址所需要的条件

八、反义

常见的反义

1、\W 匹配任意不是字母,数字,下划线,汉字的字符、

2、\S 匹配任意不是空白符的字符

3、\D 匹配任意非数字的字符

4、\B 匹配不是单词开头或结束的位置

5、[^x] 匹配除了x以外的任意字符

6、[^aeiou] 匹配除了aeiou这几个字母以外的任意字符


例子:

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

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

九、向后引用 ********************************************************************

1)说明:

使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)
可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,
规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,
第二个为2,以此类推。

2)后向引用用于重复搜索前面某个分组匹配的文本

3)\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。
这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字
(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),
最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。

4)也可以自己指定子表达式的组名。要指定一个子表达式的组名,
使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),
这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,也可以使用\k<Word>,
所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。


***********使用小括号的一些常用引用*****************************

捕获

1、(exp) 匹配exp,并捕获文本到自动命名的组里

2、(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)

3、(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号

零宽断言 (?=exp) 匹配exp前面的位置

4、(?<=exp) 匹配exp后面的位置

5、(?!exp) 匹配后面跟的不是exp的位置

6、(?<!exp) 匹配前面不是exp的位置

注释

7、(?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读


十、零宽断言***********************************************************************

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

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

十一、负向零宽断言

1、一个更复杂的例子:

(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。
(?<=<(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),
然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。
注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,
引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,
后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容
(再次提醒,不包括前缀和后缀本身)。

 

十二、注释

1、小括号的另一种用途是通过语法(?#comment)来包含注释。

例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。

2、也可以在内部用#添加注释---包含注释

要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。

例如,我们可以前面的一个表达式写成这样:

(?<= # 断言要匹配的文本的前缀
<(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签)
) # 前缀结束
.* # 匹配任意文本
(?= # 断言要匹配的文本的后缀
<\/\1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
) # 后缀结束

十三、贪婪与懒惰

1、当正则表达式中包含能接受重复的限定符时,通常的行为是
(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。
以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。
如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配

2、懒惰

只需在它后面加上一个?即可,这样.*? 表示最短匹配

例如:a.*?b 匹配最短以a开头以b结尾的单词

如果匹配单词aabab, 则匹配到的是aab或ab

3、常见懒惰限定符

1)、*? 重复任意次,但尽可能少重复
2)、+? 重复1次或更多次,但尽可能少重复
3)、?? 重复0次或1次,但尽可能少重复
4)、{n,m}? 重复n到m次,但尽可能少重复
5)、{n,}? 重复n次以上,但尽可能少重复