正则表达式(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
。
\b
:匹配单词开头或结尾的位置,如\bat\b
能匹配at
,但不能匹配cat
,ate
或kate
。
\B
:匹配不是单词开头或结尾的位置,如\Bat\B
能匹配kate
,但不能匹配cat
,ate
或at
。
记录一下其它的字符
()
:将括号内的东西视为整体,可对这个整体进行数量类限制。
|
:连接两个字符串,表示匹配时的或者关系。
\d
,\D
:表示数字/非数字字符。
\w
,\W
:表示(不是)数字字母下划线字符。
\s
,\S
:表示(不是)空白区域。
利用正则表达式进行替代时可以用$1
,$2
,\(\cdots\)来替代查找中进行省略查找的部分。
一般来说使用*.等符号进行查找时会尽量多的匹配文本串(贪婪模式),可以通过加上?来使得尽量少的匹配(非贪婪模式,一旦发现能匹配成功就停止匹配)
例如对于文本串:acacacb
如果使用a.*c
进行查找,得到的串就是acacac
。
如果使用a.*?c
进行查找,得到的串就是ac
。