“正则表达式 反向引用”的版本间的差异

来自姬鸿昌的知识库
跳到导航 跳到搜索
 
(未显示同一用户的9个中间版本)
第31行: 第31行:
 
3、反向引用
 
3、反向引用
  
圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较使用的匹配模式,这个称为反向引用,
+
圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较使用的匹配模式,这个称为<u>反向引用</u>,
  
这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用 \\ 分组号,外部反向引用$分组号
+
这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用 <u>\\ 分组号</u>,外部反向引用<u>$分组号</u>
 +
 
 +
 
 +
https://www.bilibili.com/video/BV1Eq4y1E79W?p=21
 +
 
 +
=== 反向引用案例 ===
 +
 
 +
==== 匹配2个连续的相同数字 "(\\d)\\1" ====
 +
 
 +
==== 匹配5个连续的相同数字 "(\\d)\\1\\1\\1\\1"  "(\\d)\\1{4}" ====
 +
 
 +
==== 匹配个位与千位相同,十位与百位相同的数 5225,1551 ……    "(\\d)(\\d)\\2\\1" ====
 +
 
 +
 
 +
 
 +
=== 代码示例 ===
 +
 
 +
==== 示例:查找两个相连且相同的数字,在 "hello jack tom11 jack22 yyy xxx" 中匹配 "(\\d)\\1" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "hello jack tom11 jack22 yyy xxx";
 +
 
 +
        String regStr = "(\\d)\\1";
 +
 
 +
        Pattern pattern = Pattern.compile(regStr);
 +
 
 +
        Matcher matcher = pattern.matcher(content);
 +
 
 +
        while (matcher.find()) {
 +
 
 +
            System.out.println("找到:" + matcher.group(0));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:11
 +
找到:22
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
==== 示例:查找两个相连且相同的数字,在 "hello jack14 tom11 jack22 yyy xxx" 中匹配 "(\\d)\\1" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "hello jack14 tom11 jack22 yyy xxx";
 +
 
 +
        String regStr = "(\\d)\\1";
 +
 
 +
        Pattern pattern = Pattern.compile(regStr);
 +
 
 +
        Matcher matcher = pattern.matcher(content);
 +
 
 +
        while (matcher.find()) {
 +
 
 +
            System.out.println("找到:" + matcher.group(0));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:11
 +
找到:22
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
==== 示例:查找五个相连且相同的数字,在 "hello jack14 tom11 jack22 yyy xxx" 中匹配 "(\\d)\\1{4}" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "hello jack14 tom11 jack22 yyy xxx";
 +
 
 +
        String regStr = "(\\d)\\1{4}";
 +
 
 +
        Pattern pattern = Pattern.compile(regStr);
 +
 
 +
        Matcher matcher = pattern.matcher(content);
 +
 
 +
        while (matcher.find()) {
 +
 
 +
            System.out.println("找到:" + matcher.group(0));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:11
 +
找到:22
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
==== 示例:查找五个相连且相同的数字,在 "hello33333 jack14 tom11 jack22 yyy12345 xxx" 中匹配 "(\\d)\\1{4}" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "hello33333 jack14 tom11 jack22 yyy12345 xxx";
 +
 
 +
        String regStr = "(\\d)\\1{4}";
 +
 
 +
        Pattern pattern = Pattern.compile(regStr);
 +
 
 +
        Matcher matcher = pattern.matcher(content);
 +
 
 +
        while (matcher.find()) {
 +
 
 +
            System.out.println("找到:" + matcher.group(0));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:33333
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
==== 示例:查找ABBA样式的数字,在 "h1234el9876lo33333 jack14 tom11 jack22 yyy12345 xxx" 中匹配 "(\\d)(\\d)\\2\\1" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "h1234el9876lo33333 jack14 tom11 jack22 yyy12345 xxx";
 +
 
 +
        String regStr = "(\\d)(\\d)\\2\\1";
 +
 
 +
        Pattern pattern = Pattern.compile(regStr);
 +
 
 +
        Matcher matcher = pattern.matcher(content);
 +
 
 +
        while (matcher.find()) {
 +
 
 +
            System.out.println("找到:" + matcher.group(0));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:3333
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
==== 示例:查找ABBA样式的数字,在 "h1234el9876lo33333 ja1551ck14 tom11 jack22 yyy12345 xxx" 中匹配 "(\\d)(\\d)\\2\\1" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "h1234el9876lo33333 ja1551ck14 tom11 jack22 yyy12345 xxx";
 +
 
 +
        String regStr = "(\\d)(\\d)\\2\\1";
 +
 
 +
        Pattern pattern = Pattern.compile(regStr);
 +
 
 +
        Matcher matcher = pattern.matcher(content);
 +
 
 +
        while (matcher.find()) {
 +
 
 +
            System.out.println("找到:" + matcher.group(0));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:3333
 +
找到:1551
 +
</syntaxhighlight>
 +
 
 +
=== 思考题 ===
 +
在目标字符串中检索商品编号,形式如:12321-333999111 这样的号码,
 +
 
 +
要求满足前面是一个五位数,然后一个"-"号,然后是一个九位数,连续的每三位要相同
 +
 
 +
==== 示例:在 "12321-333999111" 中匹配 "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "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));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight><syntaxhighlight lang="console">
 +
找到:12321-333999111
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
==== 反例:在 "1232-333999111" 中匹配 "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "1232-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));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight>控制台什么也不会输出,因为内容和正则表达式不匹配
 +
 
 +
 
 +
 
 +
 
 +
 
 +
==== 反例:在 "12324-333929111" 中匹配 "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}" ====
 +
<syntaxhighlight lang="java">
 +
import java.util.regex.Matcher;
 +
import java.util.regex.Pattern;
 +
 
 +
public class RegExp12 {
 +
 
 +
    public static void main(String[] args) {
 +
 
 +
        String content = "12324-333929111";
 +
 
 +
        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));
 +
 
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight>控制台什么也不会输出,因为内容和正则表达式不匹配

2022年11月20日 (日) 06:11的最新版本

https://www.bilibili.com/video/BV1Eq4y1E79W?p=20

需求:

给你一段文本,请你找出所有四个数字连在一起的字串,并且这四个数字要满足

①第1位与第4位相同

②第2位与第3位相同,

比如 1221,5775,……


要解决上面的问题,还需要再回顾以下正则表达式的几个概念:

1、分组

可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分可以看作是一个子表达式或一个分组


2、捕获

把正则表达式中子表达式(分组)匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用,

从左到右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

组0代表的是整个表达式


3、反向引用

圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较使用的匹配模式,这个称为反向引用

这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用 \\ 分组号,外部反向引用$分组号


https://www.bilibili.com/video/BV1Eq4y1E79W?p=21

反向引用案例

匹配2个连续的相同数字 "(\\d)\\1"

匹配5个连续的相同数字 "(\\d)\\1\\1\\1\\1" "(\\d)\\1{4}"

匹配个位与千位相同,十位与百位相同的数 5225,1551 …… "(\\d)(\\d)\\2\\1"

代码示例

示例:查找两个相连且相同的数字,在 "hello jack tom11 jack22 yyy xxx" 中匹配 "(\\d)\\1"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "hello jack tom11 jack22 yyy xxx";

        String regStr = "(\\d)\\1";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {

            System.out.println("找到:" + matcher.group(0));

        }

    }

}
找到:11
找到:22



示例:查找两个相连且相同的数字,在 "hello jack14 tom11 jack22 yyy xxx" 中匹配 "(\\d)\\1"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "hello jack14 tom11 jack22 yyy xxx";

        String regStr = "(\\d)\\1";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {

            System.out.println("找到:" + matcher.group(0));

        }

    }

}
找到:11
找到:22



示例:查找五个相连且相同的数字,在 "hello jack14 tom11 jack22 yyy xxx" 中匹配 "(\\d)\\1{4}"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "hello jack14 tom11 jack22 yyy xxx";

        String regStr = "(\\d)\\1{4}";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {

            System.out.println("找到:" + matcher.group(0));

        }

    }

}
找到:11
找到:22



示例:查找五个相连且相同的数字,在 "hello33333 jack14 tom11 jack22 yyy12345 xxx" 中匹配 "(\\d)\\1{4}"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "hello33333 jack14 tom11 jack22 yyy12345 xxx";

        String regStr = "(\\d)\\1{4}";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {

            System.out.println("找到:" + matcher.group(0));

        }

    }

}
找到:33333



示例:查找ABBA样式的数字,在 "h1234el9876lo33333 jack14 tom11 jack22 yyy12345 xxx" 中匹配 "(\\d)(\\d)\\2\\1"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "h1234el9876lo33333 jack14 tom11 jack22 yyy12345 xxx";

        String regStr = "(\\d)(\\d)\\2\\1";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {

            System.out.println("找到:" + matcher.group(0));

        }

    }

}
找到:3333



示例:查找ABBA样式的数字,在 "h1234el9876lo33333 ja1551ck14 tom11 jack22 yyy12345 xxx" 中匹配 "(\\d)(\\d)\\2\\1"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "h1234el9876lo33333 ja1551ck14 tom11 jack22 yyy12345 xxx";

        String regStr = "(\\d)(\\d)\\2\\1";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {

            System.out.println("找到:" + matcher.group(0));

        }

    }

}
找到:3333
找到:1551

思考题

在目标字符串中检索商品编号,形式如:12321-333999111 这样的号码,

要求满足前面是一个五位数,然后一个"-"号,然后是一个九位数,连续的每三位要相同

示例:在 "12321-333999111" 中匹配 "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "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));

        }

    }

}
找到:12321-333999111



反例:在 "1232-333999111" 中匹配 "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "1232-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));

        }

    }

}

控制台什么也不会输出,因为内容和正则表达式不匹配



反例:在 "12324-333929111" 中匹配 "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}"

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp12 {

    public static void main(String[] args) {

        String content = "12324-333929111";

        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));

        }

    }

}

控制台什么也不会输出,因为内容和正则表达式不匹配