(一)正则表达式快速入门、底层实现、语法

一、正则表达式快速入门

public class Regexp_ {
    public static void main(String[] args) {
        String conten = "2010年,Java编程语言的共同创始人之一詹姆斯·高斯林从Oracle公司辞职。2011年,甲骨文公司举行了全球性的活动,以庆祝Java7的推出,随后Java7正式发布。";

        // 1. 创建一个 Pattern 对象,模式对象,可以理解成就是一个正则表达式对象
//        Pattern pattern = Pattern.compile("[a-zA-Z]+"); // 提取内容在的所有英文单词
//        Pattern pattern = Pattern.compile("[0-9]+"); // 提取文章在所有的数字
        Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-Z]+)");// 提取内容在的所有英文单词和数字
        // 2. 创建一个匹配器对象
        Matcher matcher = pattern.matcher(conten);
        // 3. 循环匹配,匹配成功返回 true
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

正则表达式:Regular Expression【regex/RE】

二、正则表达式底层实现

public class RETheory01 {
    public static void main(String[] args) {
        String conten = "1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了" +
                "第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型" +
                "版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的" +
                "标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应" +
                "用于基于Java的应用服务器。Java 2平台的发布,是Java发展过程中最重要的一个" +
                "里程碑,标志着Java的应用开始普及。";
        // 目标:匹配所有4个数字
        // 1. \\d 表示一个任意的数字
        String regStr = "\\d\\d\\d\\d";
        // 2. 创建模式对象【即正则表达式对象】
        Pattern pattern = Pattern.compile(regStr);
        // 3. 创建匹配器
        Matcher matcher = pattern.matcher(conten);

        /**
         * matcher.find()
         * 1.根据指定的规则,定位满足规则的子字符串(比如1998)
         * 2.找到后,将 子字符串的开始的索引记录到 matcher 对象的属性 int[] groups
         *   groups[0]=0,把该子字符串的 结束的索引+1 的值记录到 groups[1]=4
         * 3.同时记录 oldLast 的值为子字符串的 结束的索引+1 的值即4,即下次执行find时,就从4开始匹配
         */
        // 循环匹配
        while (matcher.find()) {
            /**
             *      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();
             *     }
             *  1.根据 groups[0]=0 和 groups[1]=4 的记录的位置,从content开始截取子字符串返回
             */
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

正则表达式中()表示为分组
public class RETheory02 {
    public static void main(String[] args) {
        String conten = "1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了" +
                "第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型" +
                "版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的" +
                "标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应" +
                "用于基于Java的应用服务器。Java 2平台的发布,是Java发展过程中最重要的一个" +
                "里程碑,标志着Java的应用开始普及。";
        // 目标:匹配所有4个数字
        // 1. \\d 表示一个任意的数字
        // 正则表达式中()表示为分组
        String regStr = "(\\d\\d)(\\d\\d)";
        // 2. 创建模式对象【即正则表达式对象】
        Pattern pattern = Pattern.compile(regStr);
        // 3. 创建匹配器
        Matcher matcher = pattern.matcher(conten);

        /**
         * matcher.find()
         * 1.根据指定的规则,定位满足规则的子字符串(比如1998)
         * 2.找到后,将 子字符串的开始的索引记录到 matcher 对象的属性 int[] groups
         *   2.1 groups[0]=0,把该子字符串的 结束的索引+1 的值记录到 groups[1]=4
         *   2.2 记录1组【19】:groups[2]=0 groups[3]=2
         *   2.3 记录2组【98】:groups[4]=2 groups[5]=4
         *   2.4 如果有更多的分组......
         * 3.同时记录 oldLast 的值为子字符串的 结束的索引+1 的值即4,即下次执行find时,就从4开始匹配
         */
        // 循环匹配
        while (matcher.find()) {
            /**
             *      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();
             *     }
             *  1.根据 groups[0]=0 和 groups[1]=4 的记录的位置,从content开始截取子字符串返回
             *  2.根据 groups[2]=0 和 groups[3]=2 的记录的位置,从content开始截取子字符串返回
             *  3.根据 groups[4]=2 和 groups[5]=4 的记录的位置,从content开始截取子字符串返回
             */
            System.out.println("找到:" + matcher.group(0));
            System.out.println("第1组匹配的值:" + matcher.group(1));
            System.out.println("第2组匹配的值:" + matcher.group(2));
        }

三、正则表达式语法

1. 基本介绍

如果要想灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:

(1)限定符

(2)选择匹配符

(3)分组组合和反向引用符

(4)特殊字符

(5)字符匹配符

(6)定位符

2. 元字符 - 转义符【\\】

需要用到转义符号的字符有以下:【.】【*】【+】【(】【)】【$】【/】【\】【?】【[】【]】【^】【{】【}】

在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果,甚至会报错的。

public class RegExp02 {
    public static void main(String[] args) {
        String content = "abc$(abc(123(";
//        String regStr = "("; // 错误
        String regStr = "\\(";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()){
            System.out.println("找到:"+matcher.group(0));
        }
    }
}

提示:

在Java的正则表达式中,两个【\\】代表其他语言中的一个【\】

3. 元字符 - 字符匹配符

public class RegExp03 {
    public static void main(String[] args) {
        // java正则表达式默认是区分字母大小写的,如何实现不区分大小写
        String content = "a11abc$ABC";
//        String regStr = "(?i)abc"; // abc不区分大小写
//        String regStr = "a(?i)bc"; // bc不区分大小写
        String regStr = "a((?i)b)c"; // b不区分大小写
        
        // 当创建 Pattern 对象时,指定 Pattern.CASE_INSENSITIVE,表示匹配是不区分字母大小写。
        Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()){
            System.out.println("找到:"+matcher.group(0));
        }
    }
}

public class RegExp04 {
    public static void main(String[] args) {
        String content = "a11_ abc$ABC y";
//        String regStr = "[^a-z]";
//        String regStr = "[^a-z]{2}";
//        String regStr = "[^0-9]";
//        String regStr = "[ac]";
//        String regStr = "\\D";
//        String regStr = "\\w";
//        String regStr = "\\s"; // \\s 匹配任何空白字符(空格、制表符)
//        String regStr = "\\S"; // \\S 匹配任何非空白字符
        String regStr = "."; // 匹配除 \n 之外的所有字符
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()){
            System.out.println("找到:"+matcher.group(0));
        }
    }
}

4. 元字符 - 选择匹配符

在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这时你需
要用到选择匹配符号

public class RegExp05 {
    public static void main(String[] args) {
        String content = "夏天 炎热 abc";
        String regStr = "夏|炎|c"; 
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

5. 元字符 - 限定符

用于指定其前面的字符和组合项连续出现多少次

public class RegExp06 {
    public static void main(String[] args) {
        String content = "a1111111aaaaaa451hi";
//        String regStr = "a{3}"; // 表示匹配 aaa
//        String regStr = "1{4}"; // 表示匹配 1111
//        String regStr = "\\d{2}"; // 表示匹配 两位的任意数字字符

        // Java匹配默认贪婪匹配,即尽可能匹配多的,aaaa优先于aaa
//        String regStr = "a{3,4}"; // 表示匹配 aaa 或者 aaaa
//        String regStr = "1{4,5}"; // 表示匹配 1111 或者 11111
//        String regStr = "\\d{2,5}"; // 表示匹配 两位数到五位数

//        String regStr = "1+"; // 表示匹配 1个1或多个1
//        String regStr = "\\d+"; // 表示匹配 1个数字或多个数字
//        String regStr = "1*"; // 表示匹配 0个1或多个1
        String regStr = "a1?"; // 表示匹配 a或a1
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}


 

6. 元字符 - 定位符

定位符。规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置

public class RegExp07 {
    public static void main(String[] args) {
        String content = "123abc";
//        String regStr = "^[0-9]+[a-z]*"; // 表示匹配 至少1个数字开头,后接任意个小写字母的字符串
        String regStr = "^[0-9]+[a-z]+$"; // 表示匹配 至少1个数字开头,并以至少1个小写字母的字符串
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

7. 捕获分组

public class RegExp08 {

    @Test
    public void test1(){
        String content = "abc1997zzz2022";
        // 非命名分组
        String regStr = "(\\d\\d)(\\d)(\\d)"; // 表示匹配 至少1个数字开头,并以至少1个小写字母的字符串
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0)); // 匹配的字符串
            System.out.println("找到:" + matcher.group(1)); // 匹配的字符串的第1个分组的内容
            System.out.println("找到:" + matcher.group(2)); // 匹配的字符串的第2个分组的内容
            System.out.println("找到:" + matcher.group(3)); // 匹配的字符串的第3个分组的内容
        }
    }

    @Test
    public void test2(){
        String content = "abc1997zzz2022";
        // 命名分组,即可以给分组取名
        String regStr = "(?<g1>\\d\\d)(?<yi2>\\d)(\\d)"; // 表示匹配 至少1个数字开头,并以至少1个小写字母的字符串
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0)); // 匹配的字符串
            System.out.println("找到:" + matcher.group("g1")); // 匹配的字符串的"g1"分组的内容
            System.out.println("找到:" + matcher.group("yi2")); // 匹配的字符串的"yi2"分组的内容
            System.out.println("找到:" + matcher.group(3)); // 匹配的字符串的第3个分组的内容
        }
    }
}

8. 非捕获分组

public class RegExp09 {

    /**
     * 找到韩顺平教育、韩顺平老师、韩顺平同学子字符串
     */
    @Test
    public void test1() {
        String content = "hello韩顺平教育 jack韩顺平老师 韩顺平同学hello";

//        String regStr = "韩顺平教育|韩顺平老师|韩顺平同学";
        String regStr = "韩顺平(?:教育|老师|同学)"; // 非捕获分组
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }

    /**
     * 找到韩顺平这个关键字,但是要求只是查找韩顺平教育和韩顺平老师中包含有的韩顺平
     */
    @Test
    public void test2() {
        String content = "hello韩顺平教育 jack韩顺平老师 韩顺平同学hello";

        String regStr = "韩顺平(?=教育|老师)"; // 非捕获分组
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }

    /**
     * 找到韩顺平这个关键字,但是要求只是查找不是(韩顺平教育和韩顺平老师)中包含有的韩顺平
     */
    @Test
    public void test3() {
        String content = "hello韩顺平教育 jack韩顺平老师 韩顺平同学hello";

        String regStr = "韩顺平(?!教育|老师)"; // 非捕获分组
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

9. 非贪婪匹配

/**
 * 非贪婪匹配
 */
public class RegExp10 {

    @Test
    public void test1() {
        String content = "hello111111 ok";

//        String regStr = "\\d+"; // 默认是贪婪匹配
        String regStr = "\\d+?"; // 非贪婪匹配
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值