学习资料:《正则表达式必知必会》人民邮电出版社
正则表达式测试工具:http://regexr.com/
1.匹配单个字符
1.1匹配纯文本
格式:
text
说明:匹配text文本
例子:
1.2匹配任意字符
格式:
.
说明:如果想匹配任意一个字符,可将这个字符的位置用.
代替,比如想匹配cat或cot,即中间的字符可能是a也可能是o,那么就正则式就可以这么写:c.t
。
例子:
1.3匹配特殊字符
格式:
\字符
说明:拿上面的例子来说,有时候我们只想匹配.这个字符,而如果直接写.的话就会匹配一个任意字符,所以针对这种情况,可以使用转义字符\表明后面的字符有特殊含义,而不是字符本身的含义。比如上一个例子,如果只想匹配一个.
,那可以写成\.
。
例子:
2.匹配一组字符
2.1匹配多个字符中的某一个
格式:
[字符集合]
说明:拿之前cat和cot的例子来说,如果用c.t
,那么同时会匹配到crt、cct这些字符,因为中间那个字符是任意的,而如果我们只想匹配cat和cot这两个文本,那么就可以使用[],在方括号里定义可能出现的字符集合,这样在匹配时,只要字符是在这个带匹配的字符集合里的都能匹配成功。所以如果想匹配cat和cot,那么就可以写成:c[ao]t
。
例子:
2.2字符集合区间
格式:[字符集合区间]
说明:如果我们要匹配的那个位置可以是任何一个英文字符,我们该怎么写?把所有可能出现的英文字符都写一遍么?那就是[abcdefghijklmnopqrstuvwxyz]
,这才只是小写字母,如果我在加上大写字母和数字呢?是不是要疯掉了,所以字符区间就是解决这个问题,如果我们要匹配a-z的小写字母就可以这么写:[a-z]
,是不是比之前的写法简单多了。针对常用的几种匹配内容,正则表达式可以支持以下一些区间:
- A-Z:匹配从A到Z的所有大写字母
- a-z:匹配从a-z的所有小写字母
- 0-9:匹配从0-9的所有数字
例子:
2.3取非匹配
格式:
[^字符集合]
说明:之前我们说的是匹配字符集合中的字符,那么问题来了,如果我们想匹配除了a的所有字符,那怎么办?(吐个槽,a到底跟你多大仇,就是不匹配它)总不能一个个列举可能出现的字符吧。所以我们可以使用取非匹配,排除掉一个a,其他字符都可以匹配,写成:[^a]
,这样就能匹配除了a的任意字符了。
例子:
3.使用元字符
3.1对特殊字符进行转义
格式:
\元字符
说明:这其实是在1.3中讲的内容,所谓元字符,就是在正则表达式中有特殊含义的字符,比如[、]、.包括\,他们匹配的字符并不是他们本身。但如果我们确实要匹配他们本身的时候,需要用\加上该字符来匹配字符本身。
例子:
- 匹配一个数组项
array\[0\]
- 匹配文件目录
\\home\\src\\bin
3.2匹配空白字符
格式:
\元字符
说明:当需要找出原始文本中的空白字符或者换行符是怎么办呢?系统内置的几个元字符可是实现该功能。
- [\b] 回退(并删除)一个字符
- \f 换页符
- \n 换行符
- \r 回车符
- \t 制表符
- \v 垂直制表符
3.3匹配特定的字符类别
-
匹配数字与非数字
格式:\d
、\D
说明:之前说匹配数字可以用[0-9]
,其实更简单的写法是\d
,两者的意思是等价的。同理[^0-9]
与\D
也是等价的,表示匹配除了0-9的任意字符(非数字的字符)。
例子:匹配数组任意一项array\[\d\]
-
匹配数字和字符与非数字和字母
格式:\w
、\W
说明:\w
匹配任何一个字母或数字(大小写均可)或下划线,等价于[a-zA-z0-9_]
\W
匹配任何一个非字母或数字(大小写均可)或下划线,等价于[^a-zA-z0-9_]
例子:
-
匹配空白字符与非空白字符
格式:\s
、\S
说明:\s
匹配任何一个空白字符,等价于[\f\n\r\t\v]
\S
匹配任何一个非空白字符,等价于[^\f\n\r\t\v]
例子:
-
匹配十六进制值与八进制值
格式:\x
、\0
说明:\x
匹配十六进制数的前缀
\0
匹配八进制数的前缀
例子:-
\x48
值为72,对应的ASCII码是H
-
\047
值为39,对应的ASCII码是'
-
4.重复匹配
4.1有多少个匹配
-
匹配一个或多个
格式:字符+
、[字符集合]+
说明:如果想匹配一个字符或字符集合的多次重复,那么可以使用+
作为后缀。比如,a+表示匹配一个或多个连续出现的a,[0-9]+表示匹配一个或多个连续出现的数字。
例子:
-
匹配零个或多个字符
格式:字符*
、[字符集合]*
说明:+
至少需要匹配一个字符,而*
匹配的字符则是可有可无。
例子:
-
匹配零个或一个字符
格式:字符?
、[字符集合]?
说明:?匹配的字符要么出现,要么只出现一次,只有这两种情况。
例子:
4.2匹配的重复次数
-
为重复匹配次数设定一个精确值
格式:字符{重复次数}
、[字符集合]{重复次数}
说明:虽然之前说的+ * ?
功能很强大,但是很多情况下并不能满足要求,比如要匹配一个11位数的电话号码显然用任意一个功能都完不成。这时就需要引入重复次数,比如[0-9]{11}
就表示匹配连续11个出现的数字,这就能匹配像电话号码这样的要求(当然可能还有更详细地约束,比如必须以1开头,这里只是举个简单的例子)。
例子:
-
为重复匹配次数设定一个区间
格式:字符{最少重复次数,最多重复次数}
、[字符集合]{最少重复次数,最多重复次数}
说明:为重复次数设定一个最小值和最大值,表明一个字符或字符集合最少出现的次数和最多出现的次数。
例子:
-
匹配至少重复多少次
格式:字符{最少重复次数,}
、[字符集合]{最少重复次数,}
说明:有了第2点介绍的只是,这里就很好理解,为重复次数设定一个最小值,不设定最大值,那不就是表明一个字符至少出现多少次嘛!
例子:
4.3防止过度匹配
说明:之前介绍的+*{n,}都没有定义匹配次数的上限,这就很容易造成过度匹配的现象。所以有必要引入“贪婪型”字符和“懒惰型”字符的概念。
贪婪型字符有:
*、+、{n,}
对应的懒惰型字符有:
*?、+?、{n,}?
比如一个h5的页面有很多<h2>...</h2>
这样的标签,如果我们使用贪婪型字符匹配可以写成:
<h2>.*</h2>
贪婪型字符*的匹配原则是,只要没匹配到最后一个</h2>
,我就一直匹配下去,直到匹配到最后一个</h2>
。
使用懒惰型字符匹配可以写成
<h2>.*?</h2>
懒惰型字符*?的匹配原则是,只要我匹配到了后面的一个</h2>
,我就不干了,不匹配了,除非找到下一个<h2>
,我再继续匹配。
例子:
-
贪婪型字符匹配
-
懒惰型字符匹配
5.位置匹配
5.1单词边界
格式:\b单词\b
、\b单词
、单词\b
说明:什么是边界匹配呢?举个简单的例子,比如一篇英文文章,我想找其中的cat单词,于是我这么写:cat
,看起来是没问题,但是实际匹配的时候会将所有cat都找出来,当然cat这个单词能找出来是毋庸置疑的,但同时会将类似scattered这样包含cat的单词也找出来,着当然不是我们所期望的,于是引入单词边界的概念,在cat前后各加上一个\b表示这中间是一个单词,\b用来匹配一个单词的开始或结尾。注意:只有\bcat\b
才表示要匹配cat这个单词,而\bcat
、cat\b
则分别表示匹配以cat开头和以cat结尾的单词。
例子:
-
不带单词边界匹配
-
带单词边界匹配
-
匹配cat开头的单词
-
匹配cat结尾的单词
5.2字符串边界
格式:^字符串$
、^字符串
、字符串$
说明:与单词边界同理,字符串边界表示字符串的开头与结尾,分别用^、$表示。
例子:
-
cat开头字符串
-
bar结尾字符串
6.子表达式
6.1什么是子表达式
格式:
(子表达式)
说明:前面我们学过如何指定重复次数,用的是字符{重复次数}
或[字符集合]{重复次数}
,这里的重复次数只是前面的字符或者字符集合,加入我想将\d{1,3}\.
这样一个完整的表达式重复几次,那怎么办呢?我们可以用()将这样的表达式包裹起来,将括号的内容作为一个整体,再进行重复次数的表示,比如如果想找出连续出现3次cat单词,可以写成这样:(\d{1,3}\.){3}
例子:匹配IP地址
6.2子表达式的嵌套
格式:
((子表达式1)|(子表达式2))
说明:子表达式是允许嵌套的,举个例子,如果我们想匹配一串IP地址,12.159.46.200,略加思考我们不难能写出这样的正则表达式:(\d{1,3}\.){3}\d{1,3}
,但是其实这个表达式并不等价于IP地址,999.999.999.999明显不是一个IP地址,但是它是符合这个规则的,所以我们要对这个表达式中的数字要求做出修改,IP地址的四个组成部分必须符合以下要求:
- 任何一个1位数字或2位数字(0-99)——
\d{1,2}
- 任何一个以1开头的3位数字(100-199)——
1\d{2}
- 任何一个以2开头,第2位在0-4之间的3位数字(200-249)——
2[0-4]\d
- 任何一个以25开头,第3位在0-5之间的3位数字(250-255)——
25[0-5]
所以根据以上规则将原表达式改写为:
((((25[0-5])|(2[0-4]\d)|(1\d{2})|\d{1,2})|)\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|\d{1,2})|)
例子:
注意:这里将详细地规则写在前面,比如匹配200,如果检测到20是满足
\d{1,2}
的,就不会再去看后面的0了