捕获组是一种将多个字符视为一个单元的方法。通过将要分组的字符放在一组括号内来创建它们。例如,正则表达式(狗)创建一个包含字母“ d”,“ o”和“ g”的单个组。
捕获组通过从左到右计数其开括号来编号。例如,在表达式((A)(B(C)))中,有四个这样的组。
((A)(B(C)))
(A)
(B(C))
(C)
现在有个需求是去除文章中重复的“<br/>”换行标签,希望只保留一个换行标签。
public static void main(String[] args) throws Exception {
String str = " 文章第一段文章第一段文章第一段文章第一段文章第一段。<br><br><br><br> 文章第二段文章第二段文章第二段文章第二段文章第二段<br><br><br><br> 文章第三段文章第三段文章第三段文章第三段文章第三段<br>";
str = str.replaceAll("(\\s*<br\\s*/?>\\s*)\\1+", "\n<br/>\n");
System.out.println(str);
}
运行结果:
文章第一段文章第一段文章第一段文章第一段文章第一段。
<br/>
文章第二段文章第二段文章第二段文章第二段文章第二段
<br/>
文章第三段文章第三段文章第三段文章第三段文章第三段<br>
总结:
1.反向引用指的就是“\\1” 他表示前面括号里的 捕获组, 数字1表示第一个捕获组。 然后后面接+号,表示至少出现1次。加上前面括号的捕获组,即至少出现2次。
2.理解上面的含义就明白为什么运行结果中最后一个换行标签没被替换了。
因为是+号,所以必须出现2次才会进行替换的。
另外还可以在替换字符串中使用捕获组,与前面的“\\1”区别是,使用“$1”指代捕获组。例子:
System.out.println("123456789".replaceAll("(4)5(6)", "<p>$1</p>"));
输出结果是:
123<p>4</p>789