先上例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Hello {
public static void main(String[] args) {
// 正则表达式数组
String[] regs = new String[] {
"aa(?<=aa)\\w{2}",
"aa(?=aa)\\w{2}",
"(?<=aa)\\w{2}",
"\\w{2}(?<=aa)",
"(?=aa)\\w{2}",
"\\w{2}(?=aa)"
};
// 匹配正则表达式的字符串
String s = "aaabaaaa";
// 输出被匹配的字符串
System.out.println("Matched string: " + s);
System.out.println();
for(String reg : regs) {
testReg(reg, s);
System.out.println();
}
}
public static void testReg(String reg, String s) {
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(s);
System.out.println("pattern " + reg + ":");
while(matcher.find()) {
System.out.println("match begin " + matcher.start() + ": " + matcher.group());
}
}
}
运行结果:
Matched string: aaabaaaa
pattern aa(?<=aa)\w{2}:
match begin 0: aaab
match begin 4: aaaa
pattern aa(?=aa)\w{2}:
match begin 4: aaaa
pattern (?<=aa)\w{2}:
match begin 2: ab
match begin 6: aa
pattern \w{2}(?<=aa):
match begin 0: aa
match begin 4: aa
match begin 6: aa
pattern (?=aa)\w{2}:
match begin 0: aa
match begin 4: aa
match begin 6: aa
pattern \w{2}(?=aa):
match begin 2: ab
match begin 4: aa
分析:
(?=):肯定式向前查找,意思是这个非捕获组只影响前边的正则表达式匹配。
(?<=):肯定式向后查找,意思是这个非捕获组只影响后边的正则表达式匹配。
所以,对字符串 "aaabaaaa" ,
1、"aa(?<=aa)\\w{2}" 的匹配结果有两组,先是从位置0开始,有两个a,满足 正则"aa" ,又因为正则 "(?<=aa)" 是非捕获组且肯定式向后查找,只影响后边的正则表达式匹配,所以,正则 "(?<=aa)"匹配"到了位置0和1,正则"\\w{2}" 从位置2开始, 匹配位置2和3。于是, 匹配结果是 “aaaa”(0到3)、 "aaaa"(4到7).
2、"aa(?=aa)\\w{2}" 的匹配结果只有一组,先是从位置0开始,有两个a,满足正则"aa",又因为正则"(?=aa)"是非捕获组且肯定式向前查找(重点),只影响前边的正则表达式匹配,所以,正则"(?=aa)"从位置3开始查找,不匹配字符串"aaabaaaa" 的2、3位置。于是,正则表达式重新从位置4开始查找,最后匹配到位置4到7.
其他几个分析类似,能看懂上面的例子的结果,应该也就明白了这两个非捕获组的区别。