Java正则表达式捕获组
2020-12-09 本文已影响0人
bit_拳倾天下
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。捕获组是的正则操作字符串更灵活。
对应在正则表达式中就是(),每个()中匹配的字符串部分就是一个组。对应到代码中,有两种方法捕获组,分别是利用Matcher对象的 group() 方法,和直接在字符串中用 "$" 表示。
例如:
String str = "123123!A1:B1";
String regex = "(([^!\\(\\s]+)(!))?([A-Z]+\\d+):([A-Z]+\\d+)";
//方法1
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
matcher.find();
log.info("'" + matcher.group(2) + "','" + matcher.group(4) + "','" + matcher.group(5) + "'");
log.info(matcher.group(2));
//方法2
str = str.replaceAll(regex, "'$2','$4','$5'");
log.info(str);
log.info("$2");
打印结果:
21:02:49.320 [main] INFO Testor - '123123','A1','B1'
21:02:49.322 [main] INFO Testor - 123123
21:02:49.322 [main] INFO Testor - '123123','A1','B1'
21:02:49.322 [main] INFO Testor - $2
如上所示,两种方法可以实现同样的效果,但有几点需要注意:
1.调用 group() 方法前,别忘了先调用 find(),否则会报错:
java.lang.IllegalStateException: No match found
at java.util.regex.Matcher.group(Matcher.java:536)
2.捕获的第 0 组表示字符串中,匹配正则部分的整体,拿上面例子来说,match.group(0)<>"$0"<>"123123!A1:B1",是匹配部分的整体而不是字符串整体,如果字符串换成 "sum(123123!A1:B1",第 0 组还是 "123123!A1:B1",因为 "sum(" 不能匹配上面的正则。
3.当组存在嵌套的情况时,例如:( (A) (B (C) ) ),组序号遵循从外向内,从左向右的原则,如这个正则 "( (A) (B(C)) )",它的组分别是:
0:( (A) (B(C)) )
1:(A)
2:(B(C))
3:(C)
4.matcher.group()可以反复利用,"$" 却不能。
5.Matcher 类似于迭代器 Iterator,find() 方法也类似于迭代器的 next(),所以如果正则匹配到多个字符串,通常回合while配合使用,例如:
String result = "sheet2!G4-sum(test!A1:B1)-C4+sum(123123!A1:B1)+E3+sheet2!G4";
String regex = "(([^!\\(\\s]+)(!))?([A-Z]+\\d+):([A-Z]+\\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(result);
while(matcher.find()){
result= result.replaceAll(matcher.group(0),"'" + matcher.group(2) + "','" + matcher.group(4) + "','" + matcher.group(5) + "'");
}