大纲:

  1. 语法
  2. 实战
  3. 反向引用、替换

 

一、语法

捕获组:匹配子表达式内容,匹配结果以编号和显示命名的方式存在内存,可供正则本身,和替换使用。

语法:

  1. 数字编号(pattern),匹配结果保存为数字。
  2. 显示命名(?<name>pattern),匹配结果保存到变量name中。
  3. 非捕获(?:pattern),标识不需要保存的组。

二、实战

文本:1990-10-10

文本为一个日期,需要分别找出年、月、日。

2.1数字编号:

public static void main(String[] args) {
        String pattern = "(\\d+)-(\\d+)-(\\d+)";
        String word = "1990-10-14";
        final Pattern compile = Pattern.compile(pattern);
        final Matcher matcher = compile.matcher(word);
        if(matcher.find()){
            final int i = matcher.groupCount();
            System.out.println("共"+i+"组");
            for (int j = 0; j <= i; j++) {
                System.out.println("第"+j+"组:"+matcher.group(j));

            }
        }
    }
    /**
     * 共3组
     * 第0组:1990-10-10
     * 第1组:1990
     * 第2组:10
     * 第3组:14
     */

第0组为整个表达式匹配内容,剩下每组对应一个括号,顺延下去。

2.2显示命名:

public static void main(String[] args) {
        String pattern = "(?<nian>\\d+)-(?<yue>\\d+)-(?<ri>\\d+)";
        String word = "1990-10-14";
        final Pattern compile = Pattern.compile(pattern);
        final Matcher matcher = compile.matcher(word);
        if(matcher.find()){
            final int i = matcher.groupCount();
            System.out.println("共"+i+"组");
            System.out.println("年:"+matcher.group("nian"));
            System.out.println("月:"+matcher.group("yue"));
            System.out.println("日:"+matcher.group("ri"));
        }
    }
    /**
     * 共3组
     * 年:1990
     * 月:10
     * 日:14
     */

3.3非捕获组

public static void main(String[] args) {
        String pattern = "(?:\\d+)-(\\d+)-(\\d+)";
        String word = "1990-10-14";
        final Pattern compile = Pattern.compile(pattern);
        final Matcher matcher = compile.matcher(word);
        if(matcher.find()){
            final int i = matcher.groupCount();
            System.out.println("共"+i+"组");
            for (int j = 0; j <= i; j++) {
                System.out.println("第"+j+"组:"+matcher.group(j));
            }
        }
    }
    /**
     * 共2组
     * 第0组:1990-10-14
     * 第1组:10
     * 第2组:14
     */

如果年这一组我们不需要,我们就可以通过非捕获来排除它。

三、反向引用、替换

3.1在正则本身中使用捕获到的组就是反向引用

\数字编号  或  \k<显示命名>

例子:

找出重复字母

用\k<显示命名>

public static void main(String[] args) {

        String pattern = "(?<chongfu>\\w)\\k<chongfu>+";
        String word = "aaabbcdddde";
        final Pattern compile = Pattern.compile(pattern);
        final Matcher matcher = compile.matcher(word);
        while(matcher.find()){
            System.out.println(matcher.group());
        }
    }
    /**
     * aaa
     * bb
     * dddd
     */

用\数字编号>

public static void main(String[] args) {

        String pattern = "(\\w)\\1+";
        String word = "aaabbcdddde";
        final Pattern compile = Pattern.compile(pattern);
        final Matcher matcher = compile.matcher(word);
        while(matcher.find()){
            System.out.println(matcher.group());
        }
    }
    /**
     * aaa
     * bb
     * dddd
     */

3.2替换

替换用 $组号 表示

例子

把所有重复字母编成不重复的

public static void main(String[] args) {
        String word = "aaabbcdddde";
        System.out.println(word.replaceAll("(\\w)\\1+", "$1"));
    }
    /**
     * abcde
     */
01-31 17:54