最近在听一点正则表达式的视频,学到了分组的用法,但是视频中讲的比较模棱两可。从而导致了String的replaceall方法理解有偏差。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
组其实就是用来提取正则中匹配到的内容。
比如有正则表达式:abc(\d{2,5})efg,这个正则本身的意思很简单,就是字符串abc和efg之间有2到5个数字,所以字符串"abc12efg"、“abc34567efg”都能满足这个正则匹配。这个相信你能理解。
那么正则表达式模式中用小括号包起来的"\d{2,5}"这部分就叫“捕获组”,正则表达式引擎会将这部分匹配到的内容记下来,以便以后取用。java代码中,可以在调用Matcher对象的find方法得到true的返回值的时候(true说明正则表达式模式找到了符合匹配的内容),调用该Matcher对象的group(int groupNo)方法获得指定的组内容。还拿刚才那个例子来说,调用matcher.group(1)就会得到"12"、“34567”这样实际匹配的内容。这里要特别注意一下,组编号是从1开始计算的。0号组实际上就是整个正则表达式匹配到的内容。
再深入一点,上面讲到的所谓组是“捕获组”,正则引擎会记下来匹配内容,但是有时候我们不需要捕获,只是想要限制匹配,就会用到非捕获组。如果你真明白了捕获组,再看非捕获组以及前瞻后顾就明白了。
捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用(反向引用) 在表达式中使用,也可以在匹配操作完成后从匹配器检索。
Back 引用 是说在后面的表达式中我们可以使用组的编号来引用前面的表达式所捕获到的文本序列。注意:反向引用,引用的是前面捕获组中的文本而不是正则,也就是说反向引用处匹配的文本应和前面捕获组中的文本相同,这一点很重要。Back引用只是引用文本而不是表达式。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
关于replaceAll方法:replaceAll(String regex, String replacement),replacement只是一个普通字符串的。
public class RegexDemo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String temp = "18612345567";
String result = temp.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
System.out.println(result);
}
}
"$1****$2" 其实就是一个普通字符串,$1和$2就是back引用,结果就是一个字符串,所以原来我认为的replacement可以写成\\d{3}****\\d{4}是错误的。