以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。
后向引用用于重复搜索前面某个分组匹配的文本。例如:
\b(\w+)\b\s+\1\b
可以用来匹配重复的单词,像go go, 或者kitty kitty。
也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)
(或者把尖括号换成’也行:(?'Word'\w+))
,这样就把\w+
的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>
,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b
。
零宽断言
(?=exp)也叫零宽度正预测先行断言,它断言被匹配的字符串以表达式exp结尾但除了结尾以外的部分。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
| 代码/语法 | 说明 |
| — | — |
| (?=exp) | 匹配exp前面的位置 |
| (?<=exp) | 匹配exp后面的位置 |
| (?!exp) | 匹配后面跟的不是exp的位置 |
| (?<!exp) | 匹配前面不是exp的位置 |
注释
小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d \d?(?#0-199)
。
贪婪与懒惰
| 语法 | 说明 |
| — | — |
| *? | 重复任意次,但尽可能少重复 |
| +? | 重复1次或更多次,但尽可能少重复 |
| ?? | 重复0次或1次,但尽可能少重复 |
| {n,m}? | 重复n到m次,但尽可能少重复 |
| {n,}? | 重复n次以上,但尽可能少重复 |
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可
能多的字符。考虑这个表达式:a.*b
,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的
话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,
只要在它后面加上一个问号?。这样.*?
就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用
最少的重复。现在看看懒惰版的例子吧:
a.*?b
匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字
符)和ab(第四到第五个字符)。
POSIX 字符类(仅 US-ASCII)
| 语法 | 说明 |
| — | — |
| \p{Lower} | 小写字母字符:[a-z]
|
| \p{Upper} | 大写字母字符:[A-Z]
|
| \p{ASCII} | 所有 ASCII:[\x00-\x7F]
|
| \p{Alpha} | 字母字符:[\p{Lower}\p{Upper}]
|
| \p{Digit} | 十进制数字:[0-9]
|
| \p{Alnum} | 字母数字字符:[\p{Alpha}\p{Digit}]
|
| \p{Punct} | 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_{|}~
|
| \p{Graph} | 可见字符:[\p{Alnum}\p{Punct}]
|
| \p{Print} | 可打印字符:[\p{Graph}\x20]
|
| \p{Blank} | 空格或制表符:[ \t]
|
| \p{Cntrl} | 控制字符:[\x00-\x1F\x7F]
|
| \p{XDigit} | 十六进制数字:[0-9a-fA-F]
|
| \p{Space} | 空白字符:[ \t\n\x0B\f\r]
|
引用
| 语法 | 说明 |
| — | — |
| \ | Nothing,但是引用以下字符 |
| \Q | Nothing,但是引用所有字符,直到 \E |
| \E | Nothing,但是结束从 \Q 开始的引用 |
如:\Q\w+\E
表示字符串\w+
而不是正则中的单词字符:[a-zA-Z_0-9]。
其他
| 语法 | 说明 |
| — | — |
| \xhh | 十六进制值为0xhh的字符 |
| \uhhhh | 十六进制表示为0xhhhh的Unicode字符 |
| \t | 制表符Tab |
| \n | 换行符 |
| \r | 回车 |
| \f | 换页 |
| \e | 转义(Escape) |
处理选项
上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是Java中常用的正则表达式选项:
| 名称 | 说明 |
| — | — |
| CASE_INSENSITIVE | 匹配时区分大小写 |
| MULTILINE | 更改^
和$
的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$
的精确含意是:匹配\n之前的位置以及字符串结束前的位置.) |
| DOTALL | 在 dotall 模式中,表达式 . 可以匹配任何字符,包括行结束符。默认情况下,此表达式不匹配行结束符。 |
| UNICODE_CASE | 指定此标志后,由 CASE_INSENSITIVE 标