正则表达式(regular expression)提供了一种字符串匹配模式,在定义了一系列“通配符”的情况下,方便我们查找给定文本串下的满足某些特定条件的子串。
一般而言,我们用bbs
去匹配bsbsbbs
,得到的就是匹配到最后三位的结果。但假设我忘记了最后一位是什么,只记得前两位是bb
该怎么办,利用正则表达式就能解决此类问题。
字符类
这一类的符号限制匹配的字符种类。
-
.
可以用来匹配任何一个字符,如bb.
可以用来匹配bbs
或者bbq
或者bb2
. -
[]
表示匹配括号内的任何一个字符,如[abc]bc
能同时匹配到abc
,bbc
,cbc
,但是不能匹配到dbc
. -
-
表示范围,如[abc]bc
等价于[a-c]bc
. -
^
表示“非”,在[]
的开头使用,表示匹配除括号内的字符以外的任何字符,如[^abc]bc
和[^a-c]bc
能匹配到dbc
,2bc
,bc
,不能匹配到abc
,bbc
,cbc
.
注意,对于在正则表达式有特殊意义的字符,如果我们需要在文本串中匹配这个字符,则需在正则表达式中的该字符前加上,比如为了匹配
0.1
的正则表达式需要写成[0-9].[0-9]
。
数量类
这一类的字符对字符的出现次数进行限制。
-
?
表示前面的字符的出现次数(leq 1),如a?bc
能匹配到abc
和bc
,不能匹配到aabc
。 -
+
表示前面的字符的出现次数(geq 1),如a+bc
能匹配到abc
和aabc
,不能匹配到bc
。 -
*
表示前面的字符的出现次数(geq 0),如如a?bc
能匹配到abc
,bc
和aabc
。 -
{n,m}
表示前面字符的出现次数在区间([n,m])中。注意,如果没有(n)或者没有(m)则表示前面字符的出现次数没有下界/上界限制。如果大括号内只有一个数{n}
则表示前面字符的出现次数应恰好为(n)次。
有了上面的两类表达式已经可以解决一些简单的匹配问题了。
-
匹配一个三位数:
[1-9][0-9]{2}
(但其实这个会对那些长度(>3)的数进行一个分段操作,所以并不是完美的。) -
匹配无前导0的数:
[1-9][0-9]*
-
匹配C语言的标识符:
[a-zA-Z_]+[a_zA-Z0-9_]*
-
匹配邮箱地址:
[a-zA-z0-9_.-]+@[a-zA-z0-9_.-]+.[a-zA-z0-9_.-]+
(这里的中括号中的_.-
表示的就是这三个字符,只有当它们位于括号外面且需要匹配其本身时才需要加上转义符)
位置类
这一类字符对匹配的字符或串出现的位置进行限制。
-
^
:匹配行首的位置。 -
$
:匹配行尾的位置。 -
<
:匹配单词开头的位置。如<t
能匹配the
,但不能匹配cat
。 -
>
:匹配单词结尾的位置。如t>
能匹配cat
,但不能匹配the
。 -
:匹配单词开头或结尾的位置,如
at
能匹配at
,但不能匹配cat
,ate
或kate
。 -
B
:匹配不是单词开头或结尾的位置,如BatB
能匹配kate
,但不能匹配cat
,ate
或at
。
其它类
记录一下其它的字符
-
()
:将括号内的东西视为整体,可对这个整体进行数量类限制。 -
|
:连接两个字符串,表示匹配时的或者关系。 -
d
,D
:表示数字/非数字字符。 -
w
,W
:表示(不是)数字字母下划线字符。 -
s
,S
:表示(不是)空白区域。
Tips(不断更新)
-
利用正则表达式进行替代时可以用
$1
,$2
,(cdots)来替代查找中进行省略查找的部分。 -
一般来说使用*.等符号进行查找时会尽量多的匹配文本串(贪婪模式),可以通过加上?来使得尽量少的匹配(非贪婪模式,一旦发现能匹配成功就停止匹配)
例如对于文本串:acacacb
如果使用a.*c
进行查找,得到的串就是acacac
。
如果使用a.*?c
进行查找,得到的串就是ac
。