功能分类:
1.单一字符
x | 字符x(x 可代表任何合法的字符) |
\0mnn | 八进制数 0mnn 所表示的字符 |
\xhh | 十六进制值 0xhh 所表示的字符 |
\uhhhh | 十六进制值 0xhhhh 所表示的 Unicode 字符 |
\t | 制表符(“\u0009”) |
\n | 新行(换行)符(‘\u000A’) |
\r | 回车符(‘\u000D’) |
\f | 换页符(‘\u000C’) |
\a | 报警(bell)符(‘\u0007’) |
\e | Escape 符(‘\u001B’) |
\cx | x 对应的的控制符。例如,\cM匹配 Ctrl-M。x 值必须为 A~Z 或 a~z 之一。 |
2.特殊含义实体字符(串)
. | 除换行符以外任何字符(有些情况是任意字符) |
\d | 匹配 0~9 的所有数字 |
\D | 匹配非数字 |
\s | 匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等 |
\S | 匹配所有的非空白字符 |
\w | 匹配所有的单词字符,包括 0~9 所有数字、26 个英文字母和下画线_ |
\W | 匹配所有的非单词字符 |
d 是 digit 的意思,代表数字。
s 是 space 的意思,代表空白。
w 是 word 的意思,代表单词。
d、s、w 的大写形式恰好匹配与之相反的字符。
3.边界标记符
^ | 行的开头 ^abc ,表示 abc这个字符串,并且在开头 |
$ | 行的结尾 abc$,表示abc这个字符串,并且在结尾 |
\b | 单词的边界 |
\B | 非单词的边界 |
\A | 输入的开头 |
\G | 前一个匹配的结尾 |
\Z | 输入的结尾,仅用于最后的结束符 |
\z | 输入的结尾 |
4.括号表达式
(1)方括号:表示范围,方括号内可以加特殊的字符,如 - ,^ , &&
枚举 | 例如 [abc] 表示 a、b、c 其中任意一个字符;[gz]表示 g、z 其中任意一个字符 |
范围:- | 例如 [a-f] 表示 a~f 范围内的任意字符;[\\u0041-\\u0056] 表示十六进制字符 \u0041 到 \u0056 范围的字符。范围可以和枚举结合使用,如 [a-cx-z],表示 a~c、x~z 范围内的任意字符 |
求否:^ | 例如 [^abc]表示非 a、b、c 的任意字符;[^a-f] 表示不是 a~f 范围内的任意字符 |
“与”运算:&& | 例如 [a-z&& [def] ] 是 a~z 和 [def] 的交集,表示 d、e |
“并”运算 | 并运算与前面的枚举类似,直接写在一起即可。例如 [a-d [m-p] ] 表示 [a-dm-p] |
注:在中括号中,也可以使用\w,\b,\c等用法
(2)圆括号:
本身的含义:增加优先级,表示括号内的先运行
特殊用法:
()括号中的表达式,可以作为单独的匹配结果,存储在特定的方法中,python中是group方法,group(0)是匹配的全部字符串,从group(1)开始,是圆括号中存储的匹配结果。
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 |
(?=pattern) | 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?<=pattern) | 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。 |
(?<!pattern) | 反向否定预查,与正向否定预查类似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。 |
(3)花括号:表示数量
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 |
5、数量模式
符号 | 说明 |
X? | X零次或一次 [0,1] |
X+ | X一次或多次 [1,∞] |
X* | X零次次或多次 [0,∞] |
X{n} | X n 次 n |
X{n,} | X最少出现 n次 [n,∞] |
X{n,m} | X最少出现 n 次,最多出现 m 次 [n,m] |
6.匹配修饰变量,用于控制匹配模式
在js中,一般的写法是 / /g, 在斜杠中直接写正则式,在斜杠后面加修饰变量,
在java中,一般会使使用 " " , " " 前面是一个字符串,表示正则式,后面也是一个字符串,表示匹配修饰符
7、贪婪模式
1.正则匹配引擎原理:
预读取功能:在目前流行的引擎中,如java、python中,是正则式匹配文本。即以正则式为准,看文本是否匹配。读取时,会有两个缓冲区,正则式缓冲区,和带匹配文本(字符串)的缓冲区。引擎先从正则式中读取,根据正则式优先级,从左往右读取单个字符(组),再从待匹配文本的字符串缓冲区读取一个字符文本,看是否匹配。
数量模式匹配:正则式中一个数量模式的字符组,与后面的文字匹配,根据贪婪模式从最小范围或者最大范围开始匹配。如果当前数量不匹配,则增加/减少数量,直至匹配到为止。
回溯机制:回溯机制只在贪婪模式和懒惰模式中有,独占机制不进行回溯。回溯的规则是,如果数量模式字符组已经和文本匹配,进行后面的字符匹配,如果后面的字符不匹配,则会再回到之前数量模式的字符组,增加/减少数量,直至后面的字符也匹配位置。
当前的流行语言,正则引擎大多默认是贪婪模式。
2.贪婪模式匹配机制
(注)该功能是在数量模式的基础上使用的,_代表数量模式的6种简写
模式 | 说明 |
_ | 贪婪模式——优先选择最多的数量范围,倒着开始匹配范围。并且如果后面不匹配,还会减少前面范围,匹配范围内的所有情况。故称为贪婪模式。 |
_? | 懒惰模式——优先选择最少的范围,如果没有,则一步一步往上加。选择的顺序与贪婪相反而已。同样有预读取。 |
_+ | 独占模式——首先选择最多的数量范围,倒着开始匹配。在当前范围中如果某个数量已经匹配到文本,正则式继续往后走,无论后面是否能匹配,都不会再改变前面数量范围的结果 |
独占模式,就是取消了回溯机制的贪婪模式。
8、贪婪模式的例子介绍:
1.简单例子
(1)例:正则ab{1,3}bc,文本abbbcd(贪婪模式)
匹配结果为:abbbc
解释:首先正则匹配a,再匹配b{1,3},这一步中进行贪婪匹配,第一次匹配3个b。再往后还有一个b,文本也往后读取,是c,出现了不匹配。此时进行回溯,将前面的范围缩小成2个b,后面的b就也能匹配。接着正则再往后面读取c字符进行匹配。
(2)例:正则ab{2,3}?bc,文本abbbcd(懒惰模式)
匹配结果为:abbbc
正则读取到b{2,3}字符组时,首先匹配的就是b{2},在往后面还有一个b,也能匹配。这种模式同样可以进行回溯,但是在这一次中并没有使用回溯功能。
(3)例:正则ab{2,3}+bc,文本abbbcd(独占模式)
匹配结果:无
解释:正则读取到数量模式b{2,3}时,首先匹配b{3},文本中可以匹配到3个b,继续往后面匹配。正则式中还有一个b,这时文本中读取c,无法匹配,整个匹配结束,没有结果。
2.图片解释
(1)我们再来看一下究竟什么是贪婪模式。
默认情况下,这个几个特殊字符都是贪婪的,也就是说,它会根据前导字符去匹配尽可能多的内容。这也就解释了为什么在第3部分的例子中,第3步以后的事情会发生了。
(2)在以上字符后加上一个问号(?)则可以开启懒惰模式,在该模式下,正则引擎尽可能少的重复匹配字符,匹配成功之后它会继续匹配剩余的字符串。
在上例中,如果将正则换为ab{1,3}?c ,文本换为abc,则匹配过程变成了下面这样(橙色为匹配,黄色为不匹配),由此可见,在非贪婪模式下,第2步正则中的b{1,3}?与文本b匹配之后,接着去用c与文本中的c进行匹配,而未发生回溯。
(3)如果在以上四种表达式后加上一个加号(+),则会开启独占模式。同贪婪模式一样,独占模式一样会匹配最长。不过在独占模式下,正则表达式尽可能长地去匹配字符串,一旦匹配不成功就会结束匹配而不会回溯。我们以下面的表达式为例,ab{1,3}+bc
如果我们用文本"abbc"去匹配上面的表达式,匹配的过程如下图所示(橙色为匹配,黄色为不匹配),
可以发现,在第2和第3步,b{1,3}+会将文本中的2个字母b都匹配上,结果文本中只剩下一个字母c。那么在第4步时,正则中的b和文本中的c进行匹配,当无法匹配时,并不进行回溯,这时候整个文本就无法和正则表达式发生匹配。如果将正则表达式中的加号(+)去掉,那么这个文本整体就是匹配的了。
参考资料: