韩顺平Java-第二十六章:正则表达式

一 正则表达式入门

1 极速体验正则表达式威力

在这里插入图片描述

package com.hspedu.regexp;

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


  体验正则表达式的威力,给我们文本处理带来哪些便利

public class Regexp_ {
    public static void main(String[] args) {
          String context="1994年6、7月间,在经历了一场历时三天的讨论之后,团队决定再一次改变了努力的目标,这次他们决" +
                "定将该技术应用于万维网。他们认为随着Mosaic浏览器的到来,因特网正在向同样的高度互动的远景演变,而这一" +
                "远景正是他们在有线电视网中看到的。作为原型,帕特里克·诺顿写了一个小型万维网浏览器WebRunner。 [8] \n" +
                "1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,急需一种软件技术来" +
                "开发一种程序,这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物" +
                "力和财力。这个时候,Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是" +
                "按照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于网络上的传输系统,而Oak也是一种精简的语言," +
                "程序非常小,适合在网络上传输。Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种" +
                "将小程序嵌入到网页中进行执行的技术),并将Oak更名为Java。5月23日,Sun公司在Sun world会议上正式发布Java和Ho" +
                "tJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和微软等各大公司都纷纷停止了自己的相关开发项目," +
                "竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台。 [9-10]  \n" +
                "1996年1月,Sun公司发布了Java的第一个开发工具包(JDK 1.0),这是Java发展历程中的重要里程碑,标志着Java成为一" +
                "种独立的开发工具。9月,约8.3万个网页应用了Java技术来制作。10月,Sun公司发布了Java平台的第一个即时(JIT)编译器。";


        //首先先获得一个正则表达式的对象
		//Pattern pattern=Pattern.compile("[a-zA-Z]+");  //获取文中所有单词
		//Pattern pattern = Pattern.compile("[0-9]+");    //获取文中所有数字
        Pattern pattern = Pattern.compile("[0-9]+|[a-zA-Z]+");  //获取文中所有数字加单词
		//Pattern pattern = Pattern.compile("\\d\\d\\d\\d");    其中一个\\d代表一个0-9的任意数字
        //创建一个匹配器对象   就是按照一个正则表达式的要求去文本中查找
        Matcher matcher = pattern.matcher(context);

        //通过循环查找所有满足条件的字符串
        while (matcher.find()){
      		//如果找到,返回true 没有则false
            System.out.println(matcher.group());	//默认值就是0 可写可不写
        }                                                                                                                                                                                                               
    }
}

二 为什么要学正则表达式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三 正则表达式基本介绍

1 介绍

在这里插入图片描述

2 正则表达式底层实现🚩🚩

在这里插入图片描述

package com.hspedu.regexp;

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


  分析java的正则表达式的底层实现(重要.)

public class RegTheory {
    public static void main(String[] args) {

         String content = "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的应用开始普及。";
		//String regStr = "\\d\\d\\d\\d";
        String regStr = "(\\d\\d)(\\d\\d)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        /**
         * matcher.find() 完成的任务
         * 1. 根据指定的规则,定位满足规则的子字符串(比如1998)
         * 2. 找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups;
         *    group[0] = 0, 把该子字符串的结束的索引+1的值记录到 groups[1] = 4;
         * 3. 同时记录 oldLast 的值为 子字符串的结束的 索引+1的值即4 即下次执行find时 就从4开始匹配
         *
         * matcher.find() 完成的任务
         * 1. 根据指定的规则,定位满足规则的子字符串(比如(19)(98))
         * 2. 找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups;
         *    2.1 group[0] = 0, 把该子字符串的结束的索引+1的值记录到 groups[1] = 4;
         *    2.2 记录1组的()匹配到的字符串 groups[2] = 0 groups[3] = 2
         *    2.3 记录2组的()匹配到的字符串 groups[4] = 2 groups[5] = 4
         * 3. 同时记录 oldLast 的值为 子字符串的结束的 索引+1的值即4 即下次执行find时 就从4开始匹配
         */
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
            System.out.println("找到:" + matcher.group(1));//表示匹配到的子字符串的第一组子串
            System.out.println("找到:" + matcher.group(2));//表示匹配到的子字符串的第二组子串
        }
    }
}

在这里插入图片描述

四 正则表达式语法

1 元字符(转义符)

在这里插入图片描述

需要用到转移符号的字符有以下:. + ( ) $ [ ] ^ { }

package com.hspedu.regexp;

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


  演示转义字符的使用

public class RegExp02 {
    public static void main(String[] args) {
        String content = "abc$(a.bc(123(";
        //匹配( = \\(
        //匹配. = \\.
        String regStr = "\\."; //如果不加前面两个\\则代表匹配所有的字符
        //String regStr = "ddd";//在每个d前面加\\,则代表匹配3个连续任意数字,不加则匹配3个d
        //String regStr = "\\d{3}";//如果不加前面两个\\则代表匹配3个d,加上则匹配三个连续任意数字
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到"  + matcher.group(0));
        }
    }
}
(1)限定符

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

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {
               String content = "11111111aaaaaaahello";

        //String regStr = "a{3}";// 匹配 aaa
        //String regStr = "1{4}";// 匹配 1111
        //String regStr = "\\d{2}";// 匹配 两位任意数字字符

        //Java默认匹配多的(贪婪匹配)
        //String regStr = "a{3,4}";// 匹配 aaa 或 aaaa(优先)
        //String regStr = "1{4,5}";// 匹配 1111 或 11111(优先)
        //String regStr = "\\d{2,5}";// 匹配 2位数 或 3,4,5 实际 sout (找到 11111 (换行) 找到 111)

        //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, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到 " + matcher.group(0));
        }
}
(2)选择匹配符

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

在这里插入图片描述

public static void main(String[] args) {
        String content = "hanshunping|韩|寒冷";
        String regStr = "hanshunping";
        //String regStr = "韩";
        //String regStr = "寒冷";
        Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println("找到"  + matcher.group(0));
        }
    }
(3)分组组合符

a 常用分组

在这里插入图片描述

public static void main(String[] args) {

		String content = "hanshunping s7789 nn1189han";

        //String regStr = "(\\d\\d)(\\d\\d)";//匹配四个数组的字符串(7789)(1189)

        //String regStr = "(\\d\\d)(\\d)(\\d)";
        /**
         * 找到 7789
         * 第一个分组 77
         * 第二个分组 8
         * 第三个分组 9
         * 找到 1189
         * 第一个分组 11
         * 第二个分组 8
         * 第三个分组 9
         */

        String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";
        /**
         * 找到 7789
         * 第一个分组[编号] 77
         * 第二个分组[编号] 89
         * 找到 1189
         * 第一个分组[编号] 11
         * 第二个分组[编号] 89
         */

        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));
            System.out.println("第一个分组[编号] " + matcher.group("g1"));
            //System.out.println("第二个分组 " + matcher.group(2));
            System.out.println("第二个分组[编号] " + matcher.group("g2"));
            //System.out.println("第三个分组 " + matcher.group(3));
        }
}

b 特别分组

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {
        String content = "hello韩顺平教育 Jack韩顺平老师 韩顺平同学hello";
        //找到 韩顺平教育 、 韩顺平老师 、 韩顺平同学
        //String regStr = "韩顺平(?:教育|老师|同学)";//不能group(1)

        //找到 韩顺平教育中的韩顺平 韩顺平老师中的韩顺平
        //String regStr = "韩顺平(?=教育|老师)";

        //找到 不是韩顺平教育中的韩顺平 不是韩顺平老师中的韩顺平
        String regStr = "韩顺平(?!教育|老师)";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            //非捕获分组 不能使用group(1)
            System.out.println("找到 " + matcher.group(0));
        }
}
(4)字符匹配符

在这里插入图片描述

在这里插入图片描述

应用实例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {
        String content = "a11c8abcABCCy @";
        //String regStr = "[a-z]";//匹配 a-z之间任意一个字符
        //String regStr = "[A-Z]";//匹配 A-Z之间任意一个字符
        //String regStr = "abc";//匹配 abc 字符串[默认区分大小写]
        //String regStr = "(?i)abc";//匹配 abc 字符串[不区分大小写]
        //String regStr = "[0-9]";//匹配 0-9 之间任意一个字符
        //String regStr = "[^a-z]";//匹配 不在 a-z之间任意一个字符
        //String regStr = "[^0-9]";//匹配 不在 0-9之间任意一个字符
        //String regStr = "[abcd]";//匹配 在 abcd中任意一个字符
        //String regStr = "\\D";//匹配 不在 0-9的任意一个字符
        //String regStr = "\\w";//匹配 大小写英文字母, 数字,下划线
        //String regStr = "\\W";//匹配 等价于 [^a-zA-Z0-9_]
        //\\s 匹配任何空白字符(空格,制表符等)
        //String regStr = "\\s";
        //\\S 匹配任何非空白字符 ,和s刚好相反
        //String regStr = "\\S";
        //.  匹配出 \n 之外的所有字符,如果要匹配.本身则需要使用 \\.
        String regStr = ".";

        //说明
        //1. 当创建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 static void main(String[] args) {
    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));
    }
}
(5)定位符

​ 定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是结束的位置,这个也是相当有用的。

在这里插入图片描述

public static void main(String[] args) {
        //String content = "123anj-556abc-945BGh";
        //String content = "123-ljj";
        String content = "hanshunping sphan nnhan";

        //String regStr = "^[0-9]+[a-z]*";// 找到123anj
        //String regStr = "^[0-9]+\\-[a-z]+$";// 找到123-ljj
        //String regStr = "^[0-9]+\\-[a-z]+$";// 找到123-ljj

        //String regStr = "han\\b";// 找到 han (sphan) 找到 han (nnhan)
        String regStr = "han\\B";// 找到 han (hanshunping)


        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

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

五 正则表达式三个常用类

在这里插入图片描述

1 Pattern类
(1)matches方法

用于整体匹配,在验证输入的字符串是否满足条件时使用。

 public static void main(String[] args) {
         String content = "hello abc hello, 韩顺平教育";
        //String regStr = "hello";
        String regStr = "hello.*";

        boolean matches = Pattern.matches(regStr, content);
        System.out.println("整体匹配="  + matches);
    }
2 Matcher类

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {
        String content = "hello edu jack hspedutom hello smith hello hspedu hspedu";
        String regStr = "hello";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("=================");
            System.out.println(matcher.start());
            System.out.println(matcher.end());
            System.out.println("找到"  + content.substring(matcher.start(), matcher.end()));
        }

        //整体匹配方法,常用于,去校验某个字符串是否满足某个规则
        System.out.println("整体匹配=" + matcher.matches());

        //完成如果content 有 hspedu 替换成 韩顺平教育
        regStr = "hspedu";
        pattern = Pattern.compile(regStr);
        matcher = pattern.matcher(content);
        //注意:返回的字符串才是替换后的字符串 原来的 content 不变化
        String newContent = matcher.replaceAll("韩顺平教育");
        System.out.println("newContent=" + newContent);
        System.out.println("content=" + content);
}
3 PatternSyntaxException类

六 分组、捕获、反向引用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public static void main(String[] args) {
         String content = "hello hspedu11111 hello22 12345-111222333";

        //找到两个连续相同的数字
        //String regStr = "(\\d)\\1";

        //找到五个连续相同的数字
        //String regStr = "(\\d)\\1{4}";

        //找到个位与千位相同 十位与百位相同的数字
        //String regStr = "(\\d)(\\d)\\2\\1";

        //找到以下格式 "五位数-九位数连续每三位相同(例如:12345-111222333)"
        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));
        }
}

七 String类中使用正则表达式

1 替换功能

在这里插入图片描述

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 替换成JDK
    content = content.replaceAll("JDK1.3|JDK1.4", "JDK");
    System.out.println(content);
}
2 判断功能

在这里插入图片描述

public static void main(String[] args) {
        String content = "13888889999";
        if (content.matches("1(38|39)d{8}")) {
            System.out.println("验证成功");
        } else {
            System.out.println("验证失败");
        }
}
3 分割功能

在这里插入图片描述

public static void main(String[] args) {
    //要求按照 # 或者 - 或者 ~ 或者 数字 来分割
    System.out.println("===================");
    content = "hello#abc-jack12smith~北京";
    String[] split = content.split("#|-|~|\\d+");
    for (String s : split) {
        System.out.println(s);
    }
}

八 正则应用案例

在这里插入图片描述

public static void main(String[] args) {
                String content = "13588889999";
        //汉字
        //String regStr = "^[\u0391-\uffe5]+$";
        //邮政编码
        //要求:1.是1-9开头的一个六位数.  比如:123890
        //     2.
        //     3.
        //String regStr = ^[1-9]\\d{5}$;
        //QQ号码
        //要求  是1-9开头的一个(5位数-10位数)  比如  12389 , 1345687 , 187698765
        //String regStr = "^[1-9]\\d{4,9}$";

        //手机号码
        //要求 必须以13,14,15,18 开头的11位数 , 比如 13588889999
        String regStr = "^1[3|4|5|8]\\d{9}$";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        if(matcher.find()) {
            System.out.println("满足格式");
        } else {
            System.out.println("不满足格式");
        }
     
}
public static void main(String[] args) {
       //String content = "https://www.bilibili.com/video/BV1fh411y7R8?";
        String content = "https://blog.csdn.net/wthsoso/article/details/136381971";
        /** ((http|https)://)开始部分
         *  ([\w-]+\.)+[\w-]+ 匹配 www.bilibili.com
         *  (\/[\w-?=&/%.#]*)? 匹配 /video/BV1fh411y7R8?p=894&vd_source=a8223634aa8a190c7233a2dc3f8a15e3
         *  []里面的元素相当于一个集合
         *  如果查找 "(去掉http)edu.metastudy.vip/mt/official/pc/mxmt-ksjhdj"
         *  regStr = "^((http|https)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";
         */

        String regStr = "^((http|https)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        if (matcher.find()) {
            System.out.println("true");
        } else {
            System.out.println("false");
        }
     
}

在这里插入图片描述

public static void main(String[] args) {
        String content = "我....我要....学学学学....编程java!";

        //去掉所有的 .
        Pattern pattern = Pattern.compile("\\.");
        Matcher matcher = pattern.matcher(content);
        content = matcher.replaceAll("");

        System.out.println("content=" + content);

        //去掉重复的字 (.)查找任意的字符 \\1反向引用出'(.)'的内容 +指重复多次 $1表示重复字符替换为1个
        //如果要替换ABAB型 例如"我要我要" 使用(..)\\1+
        content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");

        System.out.println("content=" + content);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值