字符 | 解释 |
x | 字符 x(可代表任何合法的字符) |
\0mnn | 八进制数 0mnn 所表示的字符 |
\xhh | 十六进制值 0xhh 所表示的字符 |
\uhhhh | 十六进制值 0xhhhh所表示的 Unicode 字符 |
\t | 制表符("\u0009") |
\n | 换行符("\u000A") |
\r | 回车符("\u000D") |
\a | 报警(bell)符("\u0007") |
\e | Escape 符("\u001B") |
\cx | x 对应的控制符。例如,\cM 匹配 Ctr-M。 x 值必须为 A~Z 或 a~z 之一。 |
\f | 换页符("\u000C") |
特殊字符 | 说明 |
$ | 匹配一行的结尾。要匹配 $ 字符本身,请使用 \$ |
^ | 匹配一行的开头。要匹配 ^ 字符本身,请使用 \^ |
() | 标记子表达式的开始和结束位置。要匹配这些字符请使用 \( 和 \) |
[] | 用于确定中括号表达式的开始和结束位置。要匹配这些字符,请使用 \[ 和 \] |
{} | 用于标记前面子表达式的出现频度。要匹配这些字符,请使用 \{ 和 \} |
* | 指定前面子表达式可以出现零次或者多次。要匹配 * 字符本身,请使用 \* |
+ | 指定前面子表达式可以出现一次或多次。要匹配 + 字符本身,请使用 \+ |
? | 指定前面子表达式可以出现零次或一次。要匹配 ? 字符本身,请使用 \? |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . 字符本身,请使用 \. |
\ | 用于转义下一个字符,或指定八进制、十六进制字符。如果需要匹配 \ 字符,请用 \\ |
| | 指定两项之间任选一项。如果匹配 | 字符本身,请使用 \| |
将上面多个字符拼接起来,就可以创建一个正则表达式。例如
"\u0041\\\\" //匹配A\
"\\?\\[" //匹配?[
上面的正则表达式依然只能匹配单个字符,这是因为还未在正则表达式中使用 “通配符”,“通配符”是可以匹配多个字符的特殊字符。正则表达式中的“通配符”远远超出了普通通配符的功能,他被称为预定义字符,正则表达式支持如表 3所示的预定义字符。
表 3 预定义字符
预定义字符 | 说明 |
. | 可以匹配任何字符 |
\d | 匹配 0~9 的所有数字 |
\D | 匹配非数字 |
\s | 匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等 |
\S | 匹配所有的非空白字符 |
\w | 匹配所有的单词字符,包括 0~9 所有数字、26个英文字母和下划线(_) |
\W | 匹配所有的非单词字符 |
有了上面的预定义字符后,接下来就可以创建更强大的正则表达式了。如
c\\wt //可以匹配cat、cbt、cct、cdt、c1t等一批字符
在一些特殊情况下,例如,如果只想匹配 a~f 的字母,或者匹配除了 ab 之外的所有小写字母,或者匹配除了 ab 之外的所有小写字母,或者匹配中文字符,上面预定义字符就无能为力了,此时就需要使用方括号表达方式,方括号表达式有如表 4 所示的几种形式。
方括号表达式 | 说 明 |
表示枚举 | 例如[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-z&&[def]],求 a~z 和[def]的交集,表示 d、e 或 f [a-z&&[^bc]], a~z 范围内的所有字符,除了 b 和 c 之外,即[ad-z] [a-z&&[^m-p]],a~z 范围内的所有字符,除了 m~p 范围之外的字符,即[a-lq-z] |
表示“并”运算 | 并运算与前面的枚举类似。[a-d[m-p]],表示[a-dm-p] |
边界匹配符 | 说明 |
^ | 行的开头 |
$ | 行的结尾 |
\b | 单词的边界 |
\B | 非单词的边界 |
\A | 输入的开头 |
\G | 前一个匹配的结尾 |
\Z | 输入的结尾,仅用于最后的结束符 |
\z | 输入的结尾 |
Possessive (占有模式) :用加号后缀(+)表示,目前只有 Java 支持占有模式,通常比较少用。
三种模式的数量表示符如表 6所示。
贪婪模式 | 勉强模式 | 占用模式 | 说明 |
X? | X?? | X?? | X 表达式出现零次或一次 |
X* | X*? | X*? | X 表达式出现零次或多次 |
X+ | X+? | X+? | X 表达式出现一次或多次 |
X{n} | X{n}? | X{n}? | X 表达式出现 n 次 |
X{n,} | X{n,}? | X{n,}? | X 表达式最少出现 n 次 |
X{n,m} | X{n,m}? | X{n,m}? | X 表达式最少出现 n 次,最多出现 m 次 |
public static void main(String[] arg){
String str = "hello , java!";
System.out.println(str); //hello , java!
//贪婪模式的正则表达式
System.out.println(str.replaceFirst("\\w*", "█"));//█ , java!
//勉强模式的正则表达式
System.out.println(str.replaceFirst("\\w*?", "█"));//█hello , java!
}
当从"hell,java!"字符串中查找匹配"\\w*"子串时,因为"\\w*"使用了贪婪模式,数量标识符(*)会一直匹配下去,所以该字符串前面的所有单词字符都被他匹配到,直到遇到空格,所以替换后的效果是“█ , java!”;如果使用勉强模式,数量表示符(*)会尽量匹配最少字符,即匹配 0 个字符,所以替换后的结果是“█hello , java!”