目录
非捕获元
([0-9]|[a-z])表示数字或小写字母,用圆括号 () 将所有选择项括起来,相邻选择项用 | 分隔。
() 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)
但用圆括号会有一个副作用,使相关的匹配会被缓存,因此引入非捕获元?: 可以取消结果缓存
零宽
非捕获元和^ 代表开头,$ 代表结尾,\b 代表单词边界一样,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为"零宽"。
实例讲解:^abc[1|2] ^表示开头含义,并不会占用匹配字符串的位置,a匹配a字符位置。
代码讲解
(?=)非捕获匹配
public static void main(String[] args) {
//?: 匹配AB或者AC
Pattern pattern = Pattern.compile("A(?:B|C)");
Matcher matcher = pattern.matcher("AB");
//输出AB
while (matcher.find()){
System.out.println(matcher.group());
}
}
(?=)正向肯定预查
public static void main(String[] args) {
//?= 匹配以B或者C结尾的A字符串
Pattern pattern = Pattern.compile("A(?=B|C)");
Matcher matcher = pattern.matcher("AB");
//输出B前面的A
while (matcher.find()){
System.out.println(matcher.group());
}
}
(?!)正向否定预查
public static void main(String[] args) {
//?! 匹配不以B或者C结尾的A字符串
Pattern pattern = Pattern.compile("A(?!B|C)");
Matcher matcher = pattern.matcher("ABACAD");
//输出D前面的A
while (matcher.find()){
System.out.println(matcher.group());
}
}
(?<=)反向肯定预查
public static void main(String[] args) {
//?<= 匹配以B或者C开头的A字符串
Pattern pattern = Pattern.compile("(?<=B|C)A");
Matcher matcher = pattern.matcher("ABACAD");
//输出B后面中的A和C后面的A
while (matcher.find()){
System.out.println(matcher.group());
}
}
(?<!)反向否定预查
public static void main(String[] args) {
//?<! 匹配不以B或者C结尾的A字符串
Pattern pattern = Pattern.compile("(?<!B|C)A");
Matcher matcher = pattern.matcher("ABACAD");
//输出第一个A
while (matcher.find()){
System.out.println(matcher.group());
}
}
区别总结
非捕获单元 | 格式 | 描述 | 示例 | 说明 |
?: | (?:Pattern) | 非捕获元 | A(?=B|C) | 常用于(?:a|b)选择中,匹配AB或AC |
?= | (?=Pattern) | 正向肯定预查(零宽正向先行断言) | A(?=B|C) | 匹配以B、C结尾的A |
?! | (?=Pattern) | 正向否定预查(零宽负向先行断言) | A(?!B|C) | 匹配不以B、C结尾的A |
?<= | (?=Pattern) | 反向肯定预查(零宽正向后行断言) | (?<=B|C)A | 匹配以B、C开头的A |
?<! | (?=Pattern) | 反向否定预查(零宽负向后行断言) | (?<!B|C)A | 匹配不以B、C开头的A |
TIP:
开头结尾是相对于匹配字符串来说,不是文本的开头结尾。
参考: