Skip to content

基本介绍


问题引入 ​

(1) 提取文章中所有的英文单词 ​

(2) 提取文章中所有的数字 ​

(3) 提取文章中所有的英文单词和数字 ​

(4) 提取百度热榜 标题 ​

(5) 给你一个字符串 (或文章), 请你找出所有四个数字连在一起的子串? ​

(6) 给你一个字符串 (或文章), 请你找出所有四个数字连在一起的子串,并且这四个数字要满足:第一位与第四位相同,第二位与第三位相同,比如 1221,5775 ​

(7) 请验证输入的邮件,是否符合电子邮件格式. ​

(8) 请验证输入的手机号,是否符合手机号格式 ​

总结:可以发现以上的问题都是有需要处理文本的特性,正则表达式是处理文本的利器 ​

基本介绍 ​

(1)正则表达式(RegularExpression):简写 regexp ​

(2)正则表达式就是对字符串执行模式匹配的技术,一个正则表达式,就是用某种模式去匹配字符串的一个公式,可以高效的处理文本 ​

(3)正则表达式不只是 Java 才有,很多编程语言都支持正则表达式进行字符串操作 ​

相关方法 ​

1. Pattern(模式对象,即正则表达式对象):调用 compile("正则表示式")方法,传入匹配要求 ​

2. Matcher(匹配器):pattern.matcher(匹配字符串)获取 Matchar 对象 ​

(1)调用 find() 方法进行匹配 ​

(2)gruop()方法:匹配内容的分组,详见底层实现部分 ​

代码示例 ​

java
public class Main {
    public static void main(String[] args) {
        // 匹配内容
        String content = "123abcdefg123";
        // 创建模式对象(即正则表达式对象)
        Pattern pattern = Pattern.compile("(\\d\\d)(\\d)");
        // 创建匹配器
        Matcher matcher = pattern.matcher(content);
        // 开始匹配
        while (matcher.find()){
            System.out.println("匹配内容:" + matcher.group(0));
            System.out.println("第一组:" + matcher.group(1));
            System.out.println("第二组:" + matcher.group(2));
        }
    }
}

输出结果 ​

java
匹配内容:123
第一组:12
第二组:3
匹配内容:123
第一组:12
第二组:3

⭐ 底层实现 ​

matcher.find() ​

什么是分组? ​

一个括号表示一组,比如 (\\d\\d)(\\d),正则表达式中有两个分组,第 1 个表示第 1 组,第 2 个表示第 2 组... ​

1. 根据指定的规则,定位满足规则的字符串(比如(19)(98)) ​

2. 找到后,将字符串的开始的索引记录到 matcher 对象的属性 int[] groups: ​

group( 0 ):表示匹配字符串的左边界索引值 ​

group( 1 ):表示匹配字符串的右边界索引值 + 1 ​

group( 2 ):表示匹配字符串的第一组字串左边界索引值 ​

group( 3 ):表示匹配的字符串第一组字串右边界索引值 + 1 ​

以此类推,两个 group 值为一组 ​

(1)第一个 group 表示字符串的左索引 ​

(2)第二个 group 表示字符串的右索引 + 1 ​

除了第一组 group 表示匹配的字符串,后面的组别都表示该匹配字符串中分组的字串 ​

3. 同时记录 oldLast 的值为匹配字符串的结束的索引+1 的值,下一次执行 find 时,匹配的起始位置就从上一次 oldLast 更新的值开始开始匹配。 ​

alt text

matcher.group() ​

源码 ​

java
public String group(int group) {
    if (first < 0)
        throw new IllegalStateException("No match found");

    if (group < 0 || group > groupCount())
        throw new IndexOutOfBoundsException("No group " + group);

    if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
        return null;

    return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}

group(0):匹配的字符串 ​

group(1):匹配字符串的第一个分组字串 ​

group(2):匹配的字符串第二个分组字串 ​