day52-正则表达式03( 二 )


5.7.1反向引用的匹配原理捕获组(Expression)在匹配成功时 , 会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值 。一个捕获组(Expression)在匹配成功之前 , 它的内容可以是不确定的 , 一旦匹配成功 , 它的内容就确定了 , 反向引用的内容也就是确定的了 。
反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法 , 不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理 。

  • 看几个小案例
    1. 要匹配两个连续的相同数字(\\d)\\1
    2. 要匹配五个连续的相同数字(\\d)\\1{4}
    3. 要匹配个位与千位相同,十位与百位相同的数(\\d) (\\d)\\2\\1
    4. 在字符串中检索商品编号,形式如:12321-333999111这样的号码,要求满足前面是一个五位数 , 然后一个-号,然后是一个九位数,连续的每三位要相同
例子:
package li.regexp;import java.util.regex.Matcher;import java.util.regex.Pattern;//反向引用public class RegExp12 {public static void main(String[] args) {String content = "ke7887k5225e he12341551l12321-333999111lo ja11ck yy22y xx33333x";//1. 要匹配两个连续的相同数字(\\d)\\1//String regStr="(\\d)\\1";//2. 要匹配五个连续的相同数字(\\d)\\1{4}//String regStr="(\\d)\\1{4}";//3. 要匹配个位与千位相同,十位与百位相同的数(\\d)(\\d)\\2\\1//String regStr="(\\d)(\\d)\\2\\1";//在字符串中检索商品编号 , 形式如:12321-333999111这样的号码 , // 要求满足前面是一个五位数 , 然后一个-号 , 然后是一个九位数,连续的每三位要相同String regStr="\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()){System.out.println("找到:"+matcher.group(0));}}}5.7.2去重
经典的结巴程序
把类似“我.....我我要......学学学学.......编程java!”
这样一句话,通过正则表达式将其修改成“我要学编程java!”
package li.regexp;import java.util.regex.Matcher;import java.util.regex.Pattern;//去重public class RegExp13 {public static void main(String[] args) {String content = "我.....我我要......学学学学.......编程java!";//1.去掉所有的 .Pattern pattern = Pattern.compile("\\.");Matcher matcher = pattern.matcher(content);content = matcher.replaceAll("");//用空串替换掉.System.out.println("去掉所有的\".\"=" + content);//2.去掉重复的字//思路://2.1使用(.)\\1+去匹配连续重复的字//2.2使用反向引用$1来替换匹配到的内容//--注意:这里的正则表达式匹配的是多个重复的字,但是捕获的内容是重复的字中的一个,即圆括号pattern = Pattern.compile("(.)\\1+");//分组的捕获内容记录到$1中matcher = pattern.matcher(content);//因为正则表达式改变了,需要重置 matcherwhile (matcher.find()) {System.out.println("找到=" + matcher.group(0));}//使用反向引用$1来替换匹配到的内容//注意:虽然上面的正则表达式是匹配到的连续重复的字,但是捕获的是圆括号里面的内容,所以捕获的组里面的字只有一个,//因此使用replaceAll("$1")的意思是:用捕获到的单个字去替换匹配到的多个重复的字content = matcher.replaceAll("$1");System.out.println("去掉重复的字=" + content);//2.相当于:// content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");// System.out.println(content);}}
day52-正则表达式03

文章插图
5.8替换分割匹配5.8.1替换使用正则表达式替换字符串可以直接调用 public String replaceAll(String regex,String replacement) ,它的第一个参数是正则表达式,第二个参数是要替换的字符串 。
给出一段文本:
/*2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,几周后其获得了Apple公司Mac OS X的工业标准的支持 。2001年9月24日,J2EE1.3发布 。2002年2月26日 , J2SE1.4发布 。自此Java的计算能力有了大幅提升 。*/将这段文字中的 JDK1.3JDK1.4 统一替换成 JDK
package li.regexp;//替换public class RegExp14 {public static void main(String[] args) {String content = "2000年5月 , JDK1.3、JDK1.4和J2SE1.3相继发布,几周后其获得了" +"Apple公司Mac OS X的工业标准的支持 。2001年9月24日,J2EE1.3发布 。2002" +"年2月26日,J2SE1.4发布 。自此Java的计算能力有了大幅提升 。";//使用正则表达式,将JDK1.3/JDK1.4 统一替换成 JDKcontent = content.replaceAll("JDK1.[34]", "JDK");System.out.println(content);}}

推荐阅读