Java正则表达式 韩顺平 跟学

Java正则表达式

  • 为什么要学习正则表达式
    • 提出几个问题
  • 正则表达式
    • 正则表达式的引出
    • 基本介绍
    • 正则表达式的底层实现
  • 正则表达式语法
    • 基本介绍
    • 1.元字符转义号
      • 代码示例:
      • 匹配.
    • 2.元字符-字符匹配符
      • \\d代码示例
      • 字符匹配符 示例
      • 代码示例
    • 2.元字符-选择匹配符
    • 3.元字符-限定符
      • 举例说明
      • 非贪婪匹配
    • 4.定位符
    • 5.分组
      • 常用分组
      • 非捕获分组
  • 正则表达式应用实例
  • 正则表达式三个常用的类
    • Pattern类 的常用方法matches
    • Matches类
  • 分组、捕获、反向引用
    • 提出需求
    • 介绍
    • 案例
  • 经典的结巴程序
    • 替换功能
    • 判断功能
    • 分割功能
  • 课后习题
    • 习题1
    • 习题2
    • 习题3

为什么要学习正则表达式

Java正则表达式 韩顺平 跟学_第1张图片

package com.regexp;

import org.junit.Test;

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

/**
 * 体验正则表达式的威力
 *
 * @author wty
 * @date 2022/11/10 11:22
 */
@SuppressWarnings({"all"})
public class RegexpExperience {
    // 假定,编写了爬虫,从百度获得如下文本
    private String content = "1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、" +
            "单调的静态网页能够“灵活”起来,急需一种软件技术来开发一种程序," +
            "这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为" +
            "此纷纷投入了大量的人力、物力和财力。这个时候,Sun公司想起了那个被搁" +
            "置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是按" +
            "照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于网络上的传输系统," +
            "而Oak也是一种精简的语言,程序非常小,适合在网络上传输。" +
            "Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上" +
            "传输的Applet(Applet是一种将小程序嵌入到网页中进行执行的技术)," +
            "并将Oak更名为Java。5月23日,Sun公司在Sun world会议上正式发布Java和" +
            "HotJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和微软等" +
            "各大公司都纷纷停止了自己的相关开发项目,竞相购买了Java使用许可证," +
            "并为自己的产品开发了相应的Java平台。";

    /**
     * 提取文章中所有英文单词
     *
     * @param
     * @return void
     * @date 2022/11/10 11:33
     * @author wty
     **/
    @Test
    public void getRegexpExperienceEnglishWords(){


        // 传统方法是:遍历,代码量大,效率不高

        // 正则表达式技术
        // 1.创建一个Pattern对象,模式对象  可以理解为一个正则表达式对象
        Pattern pattern = Pattern.compile("[a-zA-z]+");

        //2.创建一个匹配器对象
        // 理解: 就是matcher匹配器按照样式pattern到content中匹配
        // 找到就返回true 否则返回false
        Matcher matcher = pattern.matcher(content);

        // 3.可以开始循环匹配
        while (matcher.find()) {
            // 匹配到内容,文本,放到m.group(0)
            System.out.println("找到;"+matcher.group(0));
        }

    }
    /**
     * 提取文章中所有的数字
     *
     * @param
     * @return void
     * @date 2022/11/10 11:33
     * @author wty
     **/
    @Test
    public void getRegexpExperienceNums(){

        // 传统方法是:遍历,代码量大,效率不高

        // 正则表达式技术
        // 1.创建一个Pattern对象,模式对象  可以理解为一个正则表达式对象
        Pattern pattern = Pattern.compile("[0-9]+");

        //2.创建一个匹配器对象
        // 理解: 就是matcher匹配器按照样式pattern到content中匹配
        // 找到就返回true 否则返回false
        Matcher matcher = pattern.matcher(content);

        // 3.可以开始循环匹配
        while (matcher.find()) {
            // 匹配到内容,文本,放到m.group(0)
            System.out.println("找到;"+matcher.group(0));
        }

    }

    /**
     * 提取文章中所有的英文单词和数字
     *
     * @param
     * @return void
     * @date 2022/11/10 11:33
     * @author wty
     **/
    @Test
    public void getRegexpExperienceEnglishWordsAndNums(){

        // 传统方法是:遍历,代码量大,效率不高

        // 正则表达式技术
        // 1.创建一个Pattern对象,模式对象  可以理解为一个正则表达式对象
        Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-Z]+)");

        //2.创建一个匹配器对象
        // 理解: 就是matcher匹配器按照样式pattern到content中匹配
        // 找到就返回true 否则返回false
        Matcher matcher = pattern.matcher(content);

        // 3.可以开始循环匹配
        while (matcher.find()) {
            // 匹配到内容,文本,放到m.group(0)
            System.out.println("找到;"+matcher.group(0));
        }

    }

    /**
     * 提取百度热榜标题
     *
     * @param
     * @return void
     * @date 2022/11/10 11:33
     * @author wty
     **/
    @Test
    public void getRegexpExperienceTitle(){

        // 传统方法是:遍历,代码量大,效率不高
        content = "\n" +
                "        
"; // 正则表达式技术 // 1.创建一个Pattern对象,模式对象 可以理解为一个正则表达式对象 Pattern pattern = Pattern.compile("); //2.创建一个匹配器对象 // 理解: 就是matcher匹配器按照样式pattern到content中匹配 // 找到就返回true 否则返回false Matcher matcher = pattern.matcher(content); // 3.可以开始循环匹配 int i = 0; while (matcher.find()) { // 匹配到内容,文本,放到m.group(1) System.out.println("热搜"+(++i)+". "+matcher.group(1)); } } /** * 提取IP地址 * * @param * @return void * @date 2022/11/10 11:33 * @author wty **/ @Test public void getRegexpExperienceIPAddress(){ // 传统方法是:遍历,代码量大,效率不高 content = "私有地址(Private address)属于非注册地址,专门为组织机构内部使用。\n" + "以下列出留用的内部私有地址\n" + "A类 10.0.0.0--10.255.255.255\n" + "B类 172.16.0.0--172.31.255.255\n" + "C类 192.168.0.0--192.168.255.255"; // 正则表达式技术 // 1.创建一个Pattern对象,模式对象 可以理解为一个正则表达式对象 Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d"); //2.创建一个匹配器对象 // 理解: 就是matcher匹配器按照样式pattern到content中匹配 // 找到就返回true 否则返回false Matcher matcher = pattern.matcher(content); // 3.可以开始循环匹配 int i = 0; while (matcher.find()) { // 匹配到内容,文本,放到m.group(0) System.out.println("IP地址"+(++i)+" "+matcher.group(0)); } } }

提出几个问题

Java正则表达式 韩顺平 跟学_第2张图片

Java正则表达式 韩顺平 跟学_第3张图片

正则表达式

正则表达式的引出

Java正则表达式 韩顺平 跟学_第4张图片

基本介绍

正则表达式的底层实现

Java正则表达式 韩顺平 跟学_第5张图片

package com.regexp;

import org.junit.Test;

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

/**分析Java正则表达式的底层原理
 *
 * 为让大家对正则表达式底层实现有一个直观的映象,给大家举个实例
 * 给你一段字符串(文本),请找出所有四个数字连在一 起的子串,比如:
 * 应该找到1998 1999 3443 9889 ===>分析底层实现RegTheory.java
 *
 * @author wty
 * @date 2022/11/10 11:55
 */

public class RegTheory {
    private String content ="1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了"+
"第二代Java平台(简称为Java2)的3个版本:J2ME(Java2MicroEdition,Java2平台的微型"+
"版),应用于移动、无线及有限资源的环境;J2SE(Java2StandardEdition,Java2平台的"+
"标准版),应用于桌面环境;J2EE(Java2EnterpriseEdition,Java2平台的企业版),应"+
"用3443于基于Java的应用服务器。Java2平台的发布,是Java发展过程中最重要的一个"+
"里程碑,标志着Java的应用开始普及9889";
    @Test
    @SuppressWarnings({"all"})
    public void regexpExperience02(){
        // 目标:找出所有四个数字连在一起的子串
        // 说明 1. \\d 表示一个任意的数字
        String regStr = "\\d\\d\\d\\d";
        //     2. 创建模式对象
        Pattern pattern = Pattern.compile(regStr);
        //     3. 创建匹配器:按照正则表达式的规则regStr匹配content字符串
        Matcher matcher = pattern.matcher(content);

        /**
         * matcher.find()
         * ---第一次---
         * 1.根据指定的规则,定位满足规则的子字符串(比如1998)
         * 2.找到后将子字符串开始的索引记录到matcher对象的属性
         * 开始位置记录到 int groups[0] = 0,
         * 子字符串结束的索引+1的值(比如1998中8是content[3],记录是3+1)记录到 groups[1] = 4,
         * 3.同时记录oldLast 的值为 子字符串结束的索引+1的值 即4,即下次执行find方法的时候就从4开始
         *group的源码
         *     public String group(int var1) {
         *         if (this.first < 0) {
         *             throw new IllegalStateException("No match found");
         *         } else if (var1 >= 0 && var1 <= this.groupCount()) {
         *             return this.groups[var1 * 2] != -1&& this.groups[var1 * 2 + 1] != -1
         *             ? this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *             : null;
         *         } else {
         *             throw new IndexOutOfBoundsException("No group " + var1);
         *         }
         *     }
         *     var1 = 0
         *     this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0 * 2], this.groups[0 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0], this.groups[1]).toString()
         *
         *
         *     根据 groups[0] = 1 和 group[1] = 4 的记录位置,从content开始截取字符串
         *     就是[0,4},包含0但是不包含4的索引位置
         *
         * ---第二次---
         * 1.根据指定的规则,定位满足规则的子字符串(比如1999)
         * 2.找到后将子字符串开始的索引记录到matcher对象的属性
         * 开始位置(1999中1的位置)记录到 int groups[0] = 31,
         * 子字符串结束的索引+1的值(比如1999中9是content[34],记录是33+1)记录到 groups[1] = 35,
         * 3.同时记录oldLast 的值为 子字符串结束的索引+1的值 即35,即下次执行find方法的时候就从35开始
         * group的源码
         *  public String group(int var1) {
         *      if (this.first < 0) {
         *          throw new IllegalStateException("No match found");
         *      } else if (var1 >= 0 && var1 <= this.groupCount()) {
         *          return this.groups[var1 * 2] != -1&& this.groups[var1 * 2 + 1] != -1
         *                  ? this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *                  : null;
         *      } else {
         *          throw new IndexOutOfBoundsException("No group " + var1);
         *              }
         *      }
         *          var1 = 0
         *      this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0 * 2], this.groups[0 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0], this.groups[1]).toString()
         *
         *
         *  根据 groups[0] = 31 和 group[1] = 35 的记录位置,从content开始截取字符串
         *  就是[31,35},包含0但是不包含35的索引位置
         *
         */
        while (matcher.find()) {
            System.out.println("找到:  " + matcher.group(0));
        }


    }

    @Test
    @SuppressWarnings({"all"})
    public void regexpExperience03(){
        // 目标:找出所有四个数字连在一起的子串
        // 说明 1. \\d 表示一个任意的数字,用括号分成2组
        String regStr = "(\\d\\d)(\\d\\d)";
        //     2. 创建模式对象
        Pattern pattern = Pattern.compile(regStr);
        //     3. 创建匹配器:按照正则表达式的规则regStr匹配content字符串
        Matcher matcher = pattern.matcher(content);

        /**
         * matcher.find()
         * ---第一次---
         * 1.根据指定的规则,定位满足规则的子字符串(比如1998)
         * 2.找到后将子字符串开始的索引记录到matcher对象的属性
         * 开始位置记录到 int groups[0] = 0,
         * 子字符串结束的索引+1的值(比如1998中8是content[3],记录是3+1)记录到 groups[1] = 4,
         * 3.同时记录oldLast 的值为 子字符串结束的索引+1的值 即4,即下次执行find方法的时候就从4开始
         *group的源码
         *     public String group(int var1) {
         *         if (this.first < 0) {
         *             throw new IllegalStateException("No match found");
         *         } else if (var1 >= 0 && var1 <= this.groupCount()) {
         *             return this.groups[var1 * 2] != -1&& this.groups[var1 * 2 + 1] != -1
         *             ? this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *             : null;
         *         } else {
         *             throw new IndexOutOfBoundsException("No group " + var1);
         *         }
         *     }
         *     var1 = 0
         *     this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0 * 2], this.groups[0 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0], this.groups[1]).toString()
         *
         *     1998 = 拆分为(19)(98)
         *     根据 groups[0] = 0 和 group[1] = 4 的记录位置, 匹配到的字符串的开始和结束索引+1
         *     第一组 记录19的起始位置和结束位置(i+1) group[2] = 0          group[3] = 2  匹配到该字符串第一组的开始和结束索引+1 即var1 = 1
         *     第二组 记录98的起始位置和结束位置(i+1) group[4] = 2         group[5] = 4   匹配到该字符串第二组的开始和结束索引+1 即var1 = 2
         *     从content开始截取字符串
         *     就是[0,4},包含0但是不包含4的索引位置
         *
         * ---第二次---
         * 1.根据指定的规则,定位满足规则的子字符串(比如1999)
         * 2.找到后将子字符串开始的索引记录到matcher对象的属性
         * 开始位置(1999中1的位置)记录到 int groups[0] = 31,
         * 子字符串结束的索引+1的值(比如1999中9是content[34],记录是33+1)记录到 groups[1] = 35,
         * 3.同时记录oldLast 的值为 子字符串结束的索引+1的值 即35,即下次执行find方法的时候就从35开始
         * group的源码
         *  public String group(int var1) {
         *      if (this.first < 0) {
         *          throw new IllegalStateException("No match found");
         *      } else if (var1 >= 0 && var1 <= this.groupCount()) {
         *          return this.groups[var1 * 2] != -1&& this.groups[var1 * 2 + 1] != -1
         *                  ? this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *                  : null;
         *      } else {
         *          throw new IndexOutOfBoundsException("No group " + var1);
         *              }
         *      }
         *          var1 = 0
         *      this.getSubSequence(this.groups[var1 * 2], this.groups[var1 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0 * 2], this.groups[0 * 2 + 1]).toString()
         *   即 this.getSubSequence(this.groups[0], this.groups[1]).toString()
         *
         *     1999 = 拆分为(19)(99)
         *     根据 groups[0] = 31 和 group[1] = 35 的记录位置,
         *     第一组 记录19的起始位置和结束位置(i+1) group[2] = 31          group[3] = 33
         *     第二组 记录99的起始位置和结束位置(i+1) group[4] = 33         group[5] = 35
         *
         *   从content开始截取字符串
         *   就是[31,35},包含0但是不包含35的索引位置
         *
         */
        while (matcher.find()) {
            // 正则表达式中()是分组的意思
            // group(0)表示匹配到的整体的子字符串
            System.out.println("找到:  " + matcher.group(0));
            // group(1)表示匹配到的的子字符串的第一组
            System.out.println("第一组():" + matcher.group(1));
            // group(2)表示匹配到的的子字符串的第二组
            System.out.println("第二组():" + matcher.group(2));
            System.out.println();
            // 分组的数字不能越界否则抛出异常
            // System.out.println("第三组():" + matcher.group(3));
            // throw new IndexOutOfBoundsException("No group " + var1);
        }


    }
}

正则表达式语法

基本介绍

Java正则表达式 韩顺平 跟学_第6张图片

1.元字符转义号

Java正则表达式 韩顺平 跟学_第7张图片

代码示例:

package com.regexp;

import org.junit.Test;

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

/**
 * 演示转义字符的使用
 *
 * @author wty
 * @date 2022/11/10 16:53
 */
public class RegexpExperience02 {
    @Test
    public void regexpExperience02(){
        String content = "abc$()awg()123()";

        // 匹配
        String regStr = "\\(";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到 "+matcher.group(0));
        }
    }
}

匹配.

    /**
     * 匹配.
     *
     * @param
     * @return void
     * @date 2022/11/10 16:58
     * @author wty
     **/
    @Test
    public void regexpExperience03(){
        String content = "abc$()awg.()123()";

        // 匹配.必须带上\\转义符
        //    否则会匹配所有字符
        String regStr = "\\.";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到 "+matcher.group(0));
        }
    }

2.元字符-字符匹配符

Java正则表达式 韩顺平 跟学_第8张图片

Java正则表达式 韩顺平 跟学_第9张图片

\d代码示例

   /**
     * \\d
     *
     * @param
     * @return void
     * @date 2022/11/10 16:58
     * @author wty
     **/
    @Test
    public void regexpExperience04(){
        String content = "abc$()awg.()123()";

        // 匹配一个3位数
        //String regStr = "\\d\\d\\d";
        // 上下两种方式等价
        String regStr = "\\d{3}";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到 "+matcher.group(0));
        }
    }

字符匹配符 示例

代码示例

package com.regexp;

import org.junit.Test;

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

/**字符匹配符
 *
 * @author wty
 * @date 2022/11/10 17:23
 */
public class RegexpExperience03 {
    @Test
    public void regexpExperience03(){
        String content = "A22c8abcABCaBC";
        //匹配 a-z 之间任意一个字
        //String regStr = "[a-z]";

        //匹配 A-Z 之间任意一个字
        //String regStr = "[A-Z]";

        // 匹配abc子串  结果只能找到abc
        //String regStr = "abc";

        // 匹配abc字串 不区分大小写 结果是abc  ABC
        //String regStr = "(?i)abc";

        // 匹配bc字串 不区分大小写 结果是bc  BC
        //String regStr = "(?i)bc";

        // 匹配abc字串 bc不区分大小写 结果是abc  aBC
        //String regStr = "a(?i)bc";

        // 匹配abc字串 b不区分大小写 结果是abc
        String regStr = "a((?i)b)c";


        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("匹配到: " + matcher.group(0));
        }
    }

    /**
     * 匹配不区分大小写
     *
     * @param
     * @return void
     * @date 2022/11/10 17:36
     * @author wty
     **/
    @Test
    public void regexpExperience04(){
        String content = "A22c8abcABCaBC";

        // 匹配abc字串 b不区分大小写 结果是abc
        String regStr = "bc";


        Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("匹配到: " + matcher.group(0));
        }
        /**查询结果
         *
         * 匹配到: bc
         * 匹配到: BC
         * 匹配到: BC
         */
    }

    /**
     * 匹配大写字母和数字
     *
     * @param
     * @return void
     * @date 2022/11/10 17:36
     * @author wty
     **/
    @Test
    public void regexpExperience05(){
        String content = "A22c8abcABCaBC2";

        // 匹配A-Z字串 结果是所有英文大写字母
        //String regStr = "[A-Z]";

        // 匹配0~9之间的任意数字
        String regStr = "[0-9]";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("匹配到: " + matcher.group(0));
        }
        /**查询结果
         *
         * 匹配到: bc
         * 匹配到: BC
         * 匹配到: BC
         */
    }
}

Java正则表达式 韩顺平 跟学_第10张图片

package com.regexp;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/10 17:43
 */
public class RegexpExperience04 {
    /**
     * 匹配非字母、非数字的字符
     *
     * @param
     * @return void
     * @date 2022/11/10 17:43
     * @author wty
     **/
    @Test
    public void RegexpExperience04(){
        String content = "A22c8abcABCaBC2";

        // 找到不是小写字母a-z的所有字符
        //String regStr = "[^a-z]";

        // 找到不是数字0-9的所有字符
        String regStr = "[^0-9]";

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到\t"+matcher.group(0));
        }

    }
}

Java正则表达式 韩顺平 跟学_第11张图片

package com.regexp;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/10 19:07
 */
public class RegexpExperience05 {
    @Test
    public void regexpExperience05(){
        String content ="A  22ce.8,abc ABC_aBC 2";
        // 可以匹配abcd中的任意一个字符,只能是小写的
        //String regStr = "[abcd]";

        // 可以匹配不是abcd中的任意一个字符,大小写字母或者数字都可以
        //String regStr = "[^abcd]";

        // \\D表示 不是0~9的数字 相当于取反
        //String regStr = "\\D";

        // w 表示任意大小写英文字母、数字和下划线
        //String regStr = "\\w";

        // \\W 表示任意大小写英文字母、数字和下划线
        //String regStr = "\\W";
        // 等价于
        //String regStr = "[^(a-zA-Z0-9_)]";

        // \\s表示匹配任何空白字符(空格制表符)
        //String regStr = "\\s";

        // \\S表示匹配任何非空白字符(和\\s相反) 除了空格和制表符都匹配上
        //String regStr = "\\S";

        // .匹配除了\n(换行符)之外的所有字符,如果要匹配.则需要\\.
        //String regStr = ".";
        String regStr = "\\.";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

2.元字符-选择匹配符

Java正则表达式 韩顺平 跟学_第12张图片

package com.regexp;

import org.junit.Test;

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

/**
 * 选择匹配符
 *
 * @author wty
 * @date 2022/11/10 19:25
 */
public class RegexpExperience06 {
    @Test
    public void regexpExperience06(){
        String content ="hanshunping韩顺平 寒";
        String regStr = "han|韩|寒";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }
    }
}

3.元字符-限定符

Java正则表达式 韩顺平 跟学_第13张图片
Java正则表达式 韩顺平 跟学_第14张图片

举例说明

Java正则表达式 韩顺平 跟学_第15张图片
Java正则表达式 韩顺平 跟学_第16张图片

package com.regexp;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/10 19:33
 */
public class RegexpExperience07 {
    @Test
    public void regexpExperience07(){
        String content = "1111111234aaahelloaaaa24";

        // 匹配连续3个a
        //String regStr = "a{3}";
        // 等价于
        //String regStr = "aaa";

        // 匹配连续4个1
        //String regStr = "1{4}";
        // 等价于
        //String regStr = "1111";


        // 匹配2位任意数字
        //String regStr = "\\d{2}";

        // 连续3个a或者连续4个a(贪婪匹配:尽可能的匹配多的,如果有4个优先匹配4个a)
        //String regStr = "a{3,4}";

        // 连续4个1或者5个1
        //String regStr = "1{4,5}";

        // 任意一个数字连续出现2次到5次
        String regStr = "\\d{2,5}";

        Pattern pattern = Pattern.compile(regStr);

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

Java正则表达式 韩顺平 跟学_第17张图片

package com.regexp;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/10 19:56
 */
public class RegexpExperience08 {
    @Test
    public void regexpExperience07(){
        String content = "a1111111234aaahelloaaaa24";

        // 匹配  1出现1次 到多次(默认贪婪匹配)
        //String regStr = "1+";

        // 匹配 任意一个数字出现1到多次(默认贪婪匹配)
        //String regStr = "\\d+";

        // 匹配 1出现0次(0次就是空)到多次(默认贪婪匹配)
        //String regStr = "1*";

        // 匹配 a出现0次或者1次
        //String regStr = "a?";

        // 匹配 a1或者a
        String regStr = "a1?";

        



        Pattern pattern = Pattern.compile(regStr);

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

非贪婪匹配

package com.regexp;

import org.junit.Test;

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

/**
 * 非贪婪匹配
 *
 * @author wty
 * @date 2022/11/11 9:12
 */
public class RegexpExperience12 {
    @Test
    public void regexpExperience12(){
        String content = "hello 1111111 ok";
        // 贪婪匹配尽可能多的数字
        //String regStr = "\\d+";
        /**
         * 结果
         * 找到1111111
         */

        // 非贪婪匹配
        String regStr = "\\d+?";
        /**
         * 结果
         * 找到1
         * 找到1
         * 找到1
         * 找到1
         * 找到1
         * 找到1
         * 找到1
         *
         * Process finished with exit code 0
         */

        Pattern pattern = Pattern.compile(regStr);

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

4.定位符

Java正则表达式 韩顺平 跟学_第18张图片

package com.regexp;

import org.junit.Test;

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

/**演示定位符的使用
 *
 * @author wty
 * @date 2022/11/10 23:02
 */
public class RegexpExperience09 {
    @Test
    public void regexpExperience09(){
        String content = "123abc";

        // 以数字开头,结尾是0个或者多个小写字母
        //String regStr = "^[0-9]+[a-z]*";
        /**
         * 结果
         *找到:123abc
         */

        // 以数字开头,结尾是0个或者多个小写字母
        content = "a123abc";
        //String regStr = "^[0-9]+[a-z]*";
        /**
         * 结果
         *空
         * 问题在于a不是以数字开头
         */

        // 以数字开头,结尾是0个或者多个小写字母
        content = "123abc2";
        //String regStr = "^[0-9]+[a-z]*";
        /**
         * 结果
         *找到:123abc
         *
         */

        // 以数字开头,结尾是0个或者多个小写字母
        content = "123";
        //String regStr = "^[0-9]+[a-z]*";
        /**
         * 结果
         *找到:123
         *
         */

        content = "123abc12";

        // 以数字开头,小写字母结尾
       // String regStr = "^[0-9]+[a-z]+$";
        /**
         * 结果
         * 空
         * 原因:结尾12是数字不是字母
         */


        content = "123abc";

        // 以数字开头,小写字母结尾
       // String regStr = "^[0-9]+[a-z]+$";
        /**
         * 结果
         * 123abc
         */

        content = "123";
        // 必须以至少1个数字开头,必须至少一个小写字母结尾
        //String regStr = "^[0-9]+[a-z]+$";
        /**
         * 结果
         * 空
         */

        content = "123-ab";
        // 必须以至少1个数字开头,必须至少一个小写字母结尾,并且中间有一个-
        //String regStr = "^[0-9]+\\-[a-z]+$";
        /**
         * 结果
         * 找到123-ab
         */


        content = "hanaiwigahgiahan";
        // 匹配目标字符串的边界,只取最后最近的那个han
        // (这里的边界不一定是最后只要是空格的都可以)
        //String regStr = "han\\b";
        /**
         * 结果
         * 找到 han
         */


        content = "hanaiwigahangiahan";
        // 匹配目标字符串的非边界,这里会取到前2个
        //String regStr = "han\\B";
        /**
         * 结果
         * 找到 han
         *
         */

        content = "hanaiwigahan giahan";
        // 匹配目标字符串的边界
        // (这里的边界不一定是最后只要是空格的都可以)
        //String regStr = "han\\b";
        /**
         * 结果
         * 找到 han
         * 找到 han
         */

        content = "hanaiwigahanty giahan";
        // 匹配目标字符串的非边界,只要不是最后那个,前面的都取出来
        // (这里的边界不一定是最后只要是空格的都可以)
        //String regStr = "han\\B";
        /**
         * 结果
         * 找到 han
         * 找到 han
         */


        content = "hanaiwigahanty giahan";
        // 匹配目标字符串的非边界,只要不是最后那个,前面的都取出来
        // (这里的边界不一定是最后只要是空格的都可以)
        String regStr = "han\\b";
        /**
         * 结果
         * 找到 han
         * 
         */


        Pattern pattern = Pattern.compile(regStr);

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

5.分组

常用分组

Java正则表达式 韩顺平 跟学_第19张图片

package com.regexp;

import org.junit.Test;

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

/**分组
 *
 * @author wty
 * @date 2022/11/10 23:38
 */
public class RegexpExperience10 {
    /**
     * 未分组的情况
     *
     * @param
     * @return void
     * @date 2022/11/10 23:42
     * @author wty
     **/
    @Test
    public void regexpExperience10(){
        String content = "hsp suibian 7788 n3175han";

        // 未分组的情况
        //String regStr = "\\d\\d\\d\\d";
        /**
         * 结果:
         * 找到:7788
         * 找到:3175
         */

        // 分组的情况
        String regStr = "(\\d\\d)(\\d\\d)";

        /**
         * 结果:
         * 找到:7788
         * 找到:3175
         */

        Pattern pattern = Pattern.compile(regStr);

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

    /**
     * 分组的情况:分成2个组
     *
     * @param
     * @return void
     * @date 2022/11/10 23:42
     * @author wty
     **/
    @Test
    public void regexpExperience11(){
        String content = "hsp suibian 7788 n3175han";

        // 分组的情况
        // 说明
        // 1.matcher.group(0) 7788
        // 2.matcher.group(1) 77
        // 3.matcher.group(2) 88
        String regStr = "(\\d\\d)(\\d\\d)";

        /**
         * 找到:7788
         * 找到第1个分组77
         * 找到第2个分组88
         * 找到:3175
         * 找到第1个分组31
         * 找到第2个分组75
         *
         */

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
            System.out.println("找到第1个分组" + matcher.group(1));
            System.out.println("找到第2个分组" + matcher.group(2));
        }
    }

    /**
     * 分组的情况 分成3个组
     *
     * @param
     * @return void
     * @date 2022/11/10 23:42
     * @author wty
     **/
    @Test
    public void regexpExperience12(){
        String content = "hsp suibian 7788 n3175han";

        // 分组的情况
        // 说明
        // 1.matcher.group(0) 7788
        // 2.matcher.group(1) 77
        // 3.matcher.group(2) 8
        // 4.matcher.group(2) 8
        String regStr = "(\\d\\d)(\\d)(\\d)";

        /**
         * 找到:7788
         * 找到第1个分组77
         * 找到第2个分组8
         * 找到第3个分组8
         * 找到:3175
         * 找到第1个分组31
         * 找到第2个分组7
         * 找到第3个分组5
         *
         */

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
            System.out.println("找到第1个分组" + matcher.group(1));
            System.out.println("找到第2个分组" + matcher.group(2));
            System.out.println("找到第3个分组" + matcher.group(3));
        }
    }

    /**
     * 命名分组
     * 分组的情况:分成2个组
     *
     * @param
     * @return void
     * @date 2022/11/10 23:42
     * @author wty
     **/
    @Test
    public void regexpExperience13(){
        String content = "hsp suibian 7788 n3175han";

        // 分组的情况
        // 说明
        // 1.matcher.group(0) 7788
        // 2.matcher.group(1) 77
        // 3.matcher.group(2) 88
        String regStr = "(?\\d\\d)(?\\d\\d)";

        /**
         * 找到:7788
         * 找到第1个分组77
         * 找到第1个分组(通过组名称来取)77
         * 找到第2个分组88
         * 找到第2个分组(通过组名称来取)88
         * 找到:3175
         * 找到第1个分组31
         * 找到第1个分组(通过组名称来取)31
         * 找到第2个分组75
         * 找到第2个分组(通过组名称来取)75
         *
         */

        Pattern pattern = Pattern.compile(regStr);

        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
            System.out.println("找到第1个分组" + matcher.group(1));
            System.out.println("找到第1个分组(通过组名称来取)" + matcher.group("g1"));
            System.out.println("找到第2个分组" + matcher.group(2));
            System.out.println("找到第2个分组(通过组名称来取)" + matcher.group("g2"));
        }
    }

}

非捕获分组

Java正则表达式 韩顺平 跟学_第20张图片

package com.regexp;

import org.junit.Test;

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

/**
 * 非捕获分组
 *
 * @author wty
 * @date 2022/11/11 0:18
 */
public class RegexpExperience11 {
    /**
     * ?:
     *
     * @param
     * @return void
     * @date 2022/11/11 0:24
     * @author wty
     **/
    @Test
    public void regexpExperience11(){
        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));
            //System.out.println("找到 "+matcher.group(1));
            /**
             * 抛出异常
             * java.lang.IndexOutOfBoundsException: No group 1
             */
        }
    }

    /**
     * ?=
     *
     * @param
     * @return void
     * @date 2022/11/11 0:24
     * @author wty
     **/
    @Test
    public void regexpExperience12(){
        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));
            //System.out.println("找到 "+matcher.group(1));
            /**
             * 抛出异常
             * java.lang.IndexOutOfBoundsException: No group 1
             */
        }
    }

    /**
     * ?!
     *
     * @param
     * @return void
     * @date 2022/11/11 0:24
     * @author wty
     **/
    @Test
    public void regexpExperience13(){
        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));
            //System.out.println("找到 "+matcher.group(1));
            /**
             * 抛出异常
             * java.lang.IndexOutOfBoundsException: No group 1
             */
        }
    }
}

正则表达式应用实例

Java正则表达式 韩顺平 跟学_第21张图片

package com.homework;

import org.junit.Test;

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

/**
 * 正则表达式的应用实例
 *
 * @author wty
 * @date 2022/11/11 9:21
 */
public class Homework01 {
    /**
     * 定位汉字
     *
     * @param
     * @return void
     * @date 2022/11/11 9:25
     * @author wty
     **/
    @Test
    public void homework01(){
        String content = "韩顺平教育";

        // 汉字(汉字的范围)
        //String regString = "^[\u0391-\uffe5]+$";
        /**
         * 结果
         *
         * 满足格式
         * 韩顺平教育
         */


        content = "韩顺平a教育";
        String regString = "^[\u0391-\uffe5]+$";
        /**
         * 结果
         *
         * 不满足格式
         *
         */




        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("满足格式");
            System.out.println(matcher.group(0));
        }else {
            System.out.println("不满足格式");
        }

    }

    /**
     * 邮政编码
     * 要求:是1-9开头的一个六位数.比如: 123890
     *
     * @param
     * @return void
     * @date 2022/11/11 9:25
     * @author wty
     **/
    @Test
    public void homework02(){
        String content = "923890";

        // 邮政编码 要求:是1-9开头的一个六位数.比如: 123890
        String regString = "^[1-9]\\d{5}";

        /**
         * 结果
         *
         * 923890
         *
         */


        content = "023890";

        // 邮政编码
        regString = "^[1-9]\\d{5}";

        /**
         * 结果
         *
         * 空
         *
         */



        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

    }

    /**
     QQ号码
     要求:是1-9开头的一个(5位数-10位数)比如: 12389 , 1345687 , 187698765
     *
     * @param
     * @return void
     * @date 2022/11/11 9:25
     * @author wty
     **/
    @Test
    public void homework03(){
        String content = "1234567890";

        // 要求:是1-9开头的一个(5位数-10位数)比如: 12389 , 1345687 , 187698765
        String regString = "^[1-9]\\d{4,9}";


        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

    }


    /**
     手机号码
     要求:必须以13,14,15,18开头的11位数,比如13588889999
     *
     * @param
     * @return void
     * @date 2022/11/11 9:25
     * @author wty
     **/
    @Test
    public void homework04(){
        String content = "13588889999";

        // 要求:必须以13,14,15,18开头的11位数,比如13588889999
        String regString = "^1(?:3|4|5|8)\\d{9}$";
        // 等价于
        regString = "^1(3|4|5|8)\\d{9}$";


        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

    }

    /**
     URL: 如图: htpt//ww.bililico./video/BV1fh411y7R8?fro=search8iseid=1831060912083761326
     *
     * @param
     * @return void
     * @date 2022/11/11 9:25
     * @author wty
     **/
    @Test
    public void homework05(){
        String content = "https://www.bilibili.com/video/BV1fh411y7R8?p=894&spm_id_from=pageDriver&vd_source=aa478ca7c2fa47ecbea3237471050046";

        // 要求:URL: 如图:
        /**
         * 思路:
         * 1.先确定 url 的开头
         */
        String regString = "^(http(?:|s)://)((\\w)+\\.)+((\\w)+\\/)+((\\w)+(\\?)\\w)(\\=(\\w)+\\&(\\w)+)*(\\=\\w+)";
        content = "http://edu.3dsmax.tech/yg/bilibili/my6652/pc/qg/05-51/index.html#201211-1?track_id=jMc0jn-hm-yHrNfVad37YdhOUh41XYmjlss9zocM26gspY5ArwWuxb4wYWpmh2Q7GzR7doU0wLkViEhUlO1qNtukyAgake2jG1bTd23lR57XzV83E9bAXWkStcAh4j9Dz7a87ThGlqgdCZ2zpQy33a0SVNMfmJLSNnDzJ71TU68Rc-3PKE7VA3kYzjk4RrKU";
        content = "bilibili.com/video/BV1fh411y7R8?p=894&spm_id_from=pageDriver&vd_source=aa478ca7c2fa47ecbea3237471050046";

        // 按照老韩的方法写
        // [.=%] 注意:在中括号里写的特殊符号,就是符号本身
        regString = "^(http(?:|s)://)?((\\w+\\.)+(\\w+))?(\\/[(\\w+)-?=#.&]*)?$";

        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

    }


    /**
     *测试中括号里的特殊字符
     *
     * @param
     * @return void
     * @date 2022/11/11 9:25
     * @author wty
     **/
    @Test
    public void homework06(){
        String content = "hello. abc 111";

        // 匹配除了/n(换行)的所有字符
        String regString = ".";
        /**
         * 结果
         *
         * h
         * e
         * l
         * l
         * o
         * .
         *
         * a
         * b
         * c
         *
         * 1
         * 1
         * 1
         *
         *
         */


        // 中括号匹配.本身
        regString = "[.]";

        /**
         * 结果
         * .
         */


        // 匹配.本身
        regString = "\\.";

        /**
         * 结果
         * .
         */

        // 匹配?本身
        regString = "[?]";

        /**
         * 结果
         *
         */

        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

    }
}

正则表达式三个常用的类

Pattern类 的常用方法matches

Java正则表达式 韩顺平 跟学_第22张图片

package com.pattern.method;

import org.junit.Test;

import java.lang.reflect.ParameterizedType;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 只是验证某个子串是否满足规则的时候,可以这样使用
 *
 * @author wty
 * @date 2022/11/11 11:02
 */
public class PatternMethod {
    @Test
    public void patternMethod(){
        String content = "hello world hi ";
        String regStr = "world";

        // 返回整体匹配的效果
        boolean matches = Pattern.matches(regStr, content);
        System.out.println(matches);
        /**
         * 结果
         * false
         */

        // 以hello开头后面任意字符
        regStr = "hello.*";
        matches = Pattern.matches(regStr, content);
        /**
         * 源码
         *
         *     public static boolean matches(String var0, CharSequence var1) {
         *         Pattern var2 = compile(var0);
         *         Matcher var3 = var2.matcher(var1);
         *         return var3.matches();
         *     }
         */
        System.out.println(matches);
        /**
         * 结果
         * true
         */

    }
}

Matches类

Java正则表达式 韩顺平 跟学_第23张图片

package com.matches.method;

import org.junit.Test;

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

/**Matches类的方法演示
 *
 * @author wty
 * @date 2022/11/11 11:18
 */
public class MatchesMethod {
    @Test
    public void matchesMethod(){
        String content = "hello edy jack tom smith hello hsp";
        String regStr = "hello";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        /**
         * 结果
         * ============
         * 0 // h对应的索引
         * 5 // o对应的索引+1
         * hello
         * ============
         * 25
         * 30
         * hello
         *
         * Process finished with exit code 0
         */

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

        // 整体匹配,常用于校验某个子串是否满足某个规则
        boolean matches = matcher.matches();
        System.out.println("整体匹配"+matches);
        /**
         * 结果
         * false
         */


        regStr = "hello.*";
        pattern = Pattern.compile(regStr);
        matcher = pattern.matcher(content);

        matches = matcher.matches();
        System.out.println("整体匹配2"+matches);
        /**
         * 结果
         * true
         */
    }
}

Java正则表达式 韩顺平 跟学_第24张图片

package com.matches.method;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/11 11:35
 */
public class MatchesMethod02 {
    @Test
    public void matchesMethod02(){
        String content = "hspeduayghoawghspeduoweg93993hspedu523257235hspedu993";
        String regStr = "hspedu";

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

        // 返回的newContent,是替换后的字符串
        String newContent = matcher.replaceAll("韩顺平教育");

        System.out.println(newContent);


    }
}

分组、捕获、反向引用

提出需求

Java正则表达式 韩顺平 跟学_第25张图片

介绍

案例

package com.regexp;

import org.junit.Test;

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

/**
 * 反向引用
 *
 * @author wty
 * @date 2022/11/11 12:36
 */
public class RegexpExperience13 {
    @Test
    public void regexpExperience13(){
        String content = "33265336aa6634666663446";


        //        1.要匹配两个连续的相同数字:
        String regStr = "(\\d)\\1";
        /**
         * 结果
         * 找到 33
         * 找到 33
         * 找到 66
         * 找到 66
         * 找到 44
         *
         */

        //        2. 要匹配五个连续的相同数字:
        regStr = "(\\d)\\1{4}";
        /**
         * 结果
         * 找到 66666
         */

        //        3.要匹配个位与干位相同,十位与百位相同的数5225 , 1551
        content = "52254444";
        regStr = "(\\d)(\\d)\\2\\1";
        /**
         * 结果
         * 找到 5225
         * 找到 4444
         */

        // 请在字符串中检索商品编号形式如:12321-333999111这
        //样的号码,要求满足前面是一个五位数,然后一个-号,然后是
        //一个九位数,连续的每三位要相同
        content = "12321-333999111";
        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));
        }
    }
}

经典的结巴程序

Java正则表达式 韩顺平 跟学_第26张图片

package com.regexp;

import org.junit.Test;

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

/**
 *
 * 把 类似 : "我....我要....学学学学....编程 java!";
 * 通过正则表达式 修改成 "我要学编程 java"
 * @author wty
 * @date 2022/11/11 14:37
 */
public class RegexpExperience14 {
    @Test
    public void regexpExperience13(){
        String content = "我....我要....学学学学....编程 java!";
        String regStr = "\\.";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        String newContent = matcher.replaceAll("");
        System.out.println(newContent);
        /**
         * 结果:
         * 我我要学学学学编程 java!
         */

        // 去掉重复的字体
        regStr = "(.)\\1+";
        pattern = Pattern.compile(regStr);
        matcher = pattern.matcher(newContent);

        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

        // 用()内的单个字符替换,整个重复字符regStr
        String result = matcher.replaceAll("$1");
        System.out.println(result);
        /**
         * 我要学编程 java!
         */

    }

    /**
     * 使用单条语句实现去重
     *
     * @param
     * @return void
     * @date 2022/11/11 15:21
     * @author wty
     **/
    @Test
    @SuppressWarnings({"all"})
    public void regexpExperience14(){
        String content = "我....我要....学学学学....编程 java!";
        // 去掉所有的.
       String regStr = "\\.";
       Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        String newContent = matcher.replaceAll("");

        System.out.println(newContent);

        // 单条语句去重
        regStr = "(.)\\1+";
        String result = Pattern.compile(regStr).matcher(newContent).replaceAll("$1");
        System.out.println(result);

    }
}

#String类中使用正则表达式

替换功能

Java正则表达式 韩顺平 跟学_第27张图片

package com.stringreg;

import org.junit.Test;

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

/**
 * String 类中使用正则表达
 * //使用正则表达式方式,将 JDK1.3 和 JDK1.4 替换成 JD
 *
 * @author wty
 * @date 2022/11/11 15:51
 */
public class StringReg {
    @Test
    public void stringReg(){
        String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布," +
                "几周后其获得了Apple公司MacOSX的工业标准的支持。2001年9月24日," +
                "J2EE1.3发布2002年2月26日,J2SE1.4发布。自此Java的计算能力有了大幅提升";
        使用正则表达式方式,将 JDK1.3 和 JDK1.4 替换成 JDK

        // 写法1:
        content = content.replaceAll("JDK1\\.(?:3|4)","JDK");
        // 写法2:
        content = content.replaceAll("JDK1\\.3|JDK1\\.4","JDK");

        System.out.println(content);
    }
}

判断功能

Java正则表达式 韩顺平 跟学_第28张图片

package com.stringreg;

import org.junit.Test;

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

/**
 * 判断功能
 * @author wty
 * @date 2022/11/11 16:06
 */
public class StringReg02 {
    @Test
    public void stringReg(){
        //要求 验证一个 手机号, 要求必须是以 138 139 开头
        String content = "13811234453";

        // 方法一:
        boolean matches = content.matches("^13(?:8|9)\\d{8}");
        System.out.println(matches);
        // 方法二:
        matches = content.matches("13(8|9)\\d{8}");
        System.out.println(matches);
    }
}

分割功能

Java正则表达式 韩顺平 跟学_第29张图片

package com.stringreg;

import org.junit.Test;

/**
 * 分割
 *
 * @author wty
 * @date 2022/11/11 16:16
 */
public class StringReg03 {
    @Test
    public void stringReg(){
        //要求 验证一个 手机号, 要求必须是以 138 139 开头
        String content = "hello#abc-jack12simith~北京";

        //要求按照 # 或者 - 或者 ~ 或者 数字 来分割

        String[] split = content.split("#|-|~");
        for (String s : split) {
            System.out.println(s);
        }
        /**
         * 结果
         * hello
         * abc
         * jack12simith
         * 北京
         *
         * Process finished with exit code 0
         */

    }
}

课后习题

习题1

Java正则表达式 韩顺平 跟学_第30张图片

package com.homework;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/11 16:27
 */
@SuppressWarnings({"all"})
public class HomeWork02 {
    @Test
    public void homeWork(){
        String content = "[email protected]";
        String regString = "^(\\w|-)+@[a-zA-Z(\\.)?]+$";

        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }

        // String 的matches 方法是整体匹配
        boolean matches = content.matches(regString);
        /**
         * 源码
         * String.class
         *     public boolean matches(String var1) {
         *         return Pattern.matches(var1, this);
         *     }
         *
         *     Pattern.class
         *         public static boolean matches(String var0, CharSequence var1) {
         *         Pattern var2 = compile(var0);
         *         Matcher var3 = var2.matcher(var1);
         *         return var3.matches();
         *     }
         *
         *     Pattern.class
         *        public Matcher matcher(CharSequence var1) {
         *         if (!this.compiled) {
         *             synchronized(this) {
         *                 if (!this.compiled) {
         *                     this.compile();
         *                 }
         *             }
         *         }
         *
         *         Matcher var2 = new Matcher(this, var1);
         *         return var2;
         *     }
         *
         *     Matcher.class
         *         Matcher(Pattern var1, CharSequence var2) {
         *         this.parentPattern = var1;
         *         this.text = var2;
         *         int var3 = Math.max(var1.capturingGroupCount, 10);
         *         this.groups = new int[var3 * 2];
         *         this.locals = new int[var1.localCount];
         *         this.reset();
         *     }
         */
        System.out.println(matches);
    }
}

习题2

Java正则表达式 韩顺平 跟学_第31张图片

package com.homework;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/11 16:50
 */
public class HomeWork03 {
    @Test
    public void HomeWork(){
        // 思路:
        // 1.先写出简单的正则表达式
        // 2.再逐步根据情况完善表达式
        String content = "0.1123";
        // 数字开头是1-9 后面跟多个数字
        String regString = "^[-+]?(([1-9]\\d*)|0?)(\\.)?(\\d)*$";


        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到:" + matcher.group(0));
        }

        boolean matches = content.matches(regString);
        System.out.println(matches);

    }
}

习题3

Java正则表达式 韩顺平 跟学_第32张图片

package com.homework;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/11/11 17:18
 */
public class HomeWork04 {
    @Test
    public void HomeWork(){
        String url = "http://www.sohu.com:8080/abc/xxx/yyy/index.html";
        url = "http://www.sohu.com:8080/index.html";
        url = "http://www.sohu.com:8080/[email protected]";

        String regStr = "^(\\w+)://((\\w+\\.?)+):((\\d)+)/(\\w+/+)*(\\w+\\.\\w+)$";
        regStr = "^(\\w+)://((\\w+\\.?)+):((\\d)+)/(\\w+/+)*([\\w.~@-]+)$";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(url);
        while (matcher.find()) {
            System.out.println("找到 " + matcher.group(0));
            System.out.println("协议 " + matcher.group(1));
            System.out.println("域名 "+ matcher.group(2));
            System.out.println("端口名 "+ matcher.group(4));
            System.out.println("文件名 "+ matcher.group(7));
        }
    }
}

你可能感兴趣的:(Java自学总结,韩顺平,java,正则表达式)