表示单个字符。例如a,它将匹配字符串中第一次出现的字符a;它也能够匹配第二个 a,这必须是你告诉正则表达式引擎从第一次匹配的地方开始搜索。正则表达式
可使用特殊字符序列表明某些不可显示字符。测试
构造 | 匹配 |
B | 字符B |
\xhh | 十六进制值为oxhh的字符 |
\uhhhh | 十六进制值为oxhhhh的Unicode字符 |
\t | 制表符Tab:(‘\u0009’) |
\r | 回车符:(‘\u000D’) |
\n | 换行符:(‘\u000A’) |
\f | 换页符:(‘\u000C’) |
\e | 转义符(Escape):(‘\u001B’) |
字符集是由一对括号[]括起来的字符集合。使用字符集,能够告诉正则表达式引擎仅仅匹配多个字符中的一个。
spa
字符集能够出如今其它字符集中,而且能够包含并集运算符(隐式)和交集运算符 (&&)。
code
构造 | 匹配 |
[abc] | a、b或c(等效于a|b|c) |
[^abc] | 除了a、b或c的任何字符(否认) |
[a-zA-Z] | a到z或A到Z的任何字符(范围) |
[abc[hij]] | a、b、c、h、i或j,等效于a|b|c|h|i|j(并集) |
[a-z&&[hij]] | h、i或j(交集) |
并集和交集的应用示例以下:字符串
[a-c[h-j]]table
a到c或h到j的任何字符(并)test
[a-z&&[^hij]]扩展
a到z,除了h、i、j(减去),等效于[a-gk-z]搜索
[a-z&&[^h-j]]引用
a到z,而非h到j(减去),等效于[a-gk-z]
预约义字符集能够用在方括号以内或以外。
例如\s\d匹配一个空白符后面紧跟一个数字;[\s\d]匹配单个空白符或数字。
构造 | 匹配 |
\d | 数字:[0-9] |
\D | 非数字:[^0-9] |
\s | 空白字符:空格、制表、回车、换行、换页 |
\S | 非空白字符:[^\s] |
\w | 单词字符:[a-zA-Z_0-9] |
\W | 非单词字符:[^\w] |
构造 | 匹配 |
^ | 输入序列的开始 当启用多行模式后,还能够匹配行的开始 |
$ | 输入序列的结尾 当启用多行模式后,还能够匹配行的结尾 |
\b | 单词边界
|
\B | 非单词边界:[^\b] \B匹配的位置是两个“单词字符”之间或两个“非单词字符”之间的位置 |
\G | 上一个匹配的结尾 |
构造 | 匹配 |
XY | X后跟Y |
X|Y | X或Y 匹配分支条件时,将会从左到右地测试每一个条件,若是知足了某个分支的话,就不会去再管其它的条件了。例如\d{5}|\d{5}-\d{4},只会匹配5位数字以及9位数字的前5位 |
(X) | 捕获组(capturing group)。能够在表达式中用\i引用第i个捕获组 |
量词描述了一个模式吸取输入文本的模式。
贪婪型:量词老是贪婪的,除非有其它的选项被设置。贪婪表达式会为全部可能的模式发现尽量多的匹配。
懒惰型:懒惰型表达式匹配知足模式所需的最少字符数。
占有型:目前,占有型量词只在Java语言中可用。当正则表达式被应用于字符串时,它会产生至关多的状态,以便在匹配失败时能够回溯。而占有型量词并不保存这些中间状态,所以它能够防止回溯。它们经常用来防止正则表达式失控,所以可使正则表达式执行起来更有效。
贪婪型 | 懒惰型 | 占有型 | 如何匹配 |
X? | X?? | X?+ | 0次或1次X(等效于X{0,1}) 事实上表示前导字符是可选的 |
X* | X*? | X*+ | 0次或屡次X(等效于X{0,} ) 事实上表示前导字符能够出现任意次数 |
X+ | X+? | X++ | 1次或屡次X(等效于X{1,} ) 事实上表示前导字符至少重现1次 |
X{n} | X{n}? | X{n}+ | 刚好n次X |
X{n,} | X{n,}? | X{n,}+ | 至少n次X |
X{n,m} | X{n,m}? | X{n,m}+ | X至少n次,且不超过m次 |
量词的贪婪性
量词?+*会致使正则表达式引擎尽量的重复前导字符。只有当这种重复会引发整个正则表达式匹配失败的状况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,而后处理正则表达式余下的部分。
例如,用一个正则表达式匹配一个HTML标签。
输入字符串为”This is a <EM>first</EM> test”,正则表达式<.+>返回”<EM>first</EM>”。这是由于+是贪婪性的。
让咱们来看看正则引擎的处理过程。
正则表达式的第一个符号是“<”,这是一个字符;第二个符号是“.”,匹配了字符“E”;第三个符号是“+”,它能够一直能够匹配后面的字符,直到一行的结束;而后遇到了换行符,匹配失败(“.”不匹配换行符)。因而引擎开始对下一个正则表达式符号进行匹配,也即试图匹配“>”。到目前为止,正则表达式“<.+”已经匹配了“<EM>first</EM> test”。引擎会试图将“>”与换行符进行匹配,结果失败了。因而引擎进行回溯,“<.+”匹配“<EM>first</EM> tes”,因而引擎将“>”与“t”进行匹配,显然仍是会失败。这个过程继续,直到“<.+”匹配“<EM>first</EM”,“>”与“>”匹配。最后引擎找到了一个匹配的部分“<EM>first</EM>”。
由于正则导向的引擎是“急切的”,因此它会急着报告它找到的第一个匹配。而不是继续回溯,即便可能会有更好的匹配,例如“<EM>”。因此因为“+”的贪婪性,使得引擎返回了一个最长的匹配。
可使用下列方式来解决量词的贪婪性带来的问题。
用懒惰性取代贪婪性。
输入字符串为”This is a <EM>first</EM> test”,正则表达式<.+?>返回”<EM>”。
让咱们再来看看正则引擎的处理过程。
正则表达式符号“<”会匹配素如字符串的第一个“<”。下一个正则符号是“.”。此次是一个懒惰的“+?”来重复上一个字符,它会尽量少的重复上一个字符。所以引擎匹配“.”和字符“E”,而后用“>”匹配“M”,结果失败了。引擎会进行回溯,和上一个例子不一样,由于是惰性重复,因此引擎是扩展惰性重复而不是减小;因而“<.+”如今被扩展为“<EM”。引擎继续匹配下一个符号“>”。此次获得了一个成功匹配。引擎因而报告“<EM>”是一个成功的匹配。
惰性扩展的一个替代方案。
输入字符串为”This is a <EM>first</EM> test”,正则表达式<[^>]+>返回”<EM>”。
这是一个更好的替代方案。能够用一个贪婪重复与一个取反字符集<[^>]+>。之因此说这是一个更好的方案在于使用惰性重复时,引擎会在找到一个成功匹配前对每个字符进行回溯。而使用取反字符集则不须要进行回溯。