正则表达式笔记

正则表达式

1、正则表达式演示

在这里插入图片描述

package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 正则表达式演示,快速入门
 * @date 2024/5/25 10:21:47
 */
public class Regexp_ {
    public static void main(String[] args) {
        //假定编写了爬虫获得了以下文本内容,
        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平台。";
        //获取文章中所有英文单词
        //获取文章中所有数字
        //获取文章中所有英文单词和数字
        //(1)、传统方法:遍历文本得到英文单词(代码量大,效率低)
        //(2)、用正则表达式

        //1。创建一个pattern对象,模式对象,可以理解就是一个正则表达式对象
        //Pattern pattern = Pattern.compile("[a-zA-Z]+");
        //Pattern pattern = Pattern.compile("[0-9]+");
        Pattern pattern = Pattern.compile("([a-zA-Z]+)|([0-9]+)");
        //2。创建一个匹配器对象
        /*
            理解:就是matcher匹配器按照pattern(模式/样式),到content文本中去匹配
                找到就返回true,否则就返回false
         */
        Matcher matcher = pattern.matcher(content);
        //3。下面开始循环匹配
        while(matcher.find()){
            //匹配内容/文本,放到matcher.group(0)
            System.out.println("找到:"+matcher.group(0));
        }
    }
}

2、为什么要学习正则表达式

我们遇到的问题:

  1. 给你一个字符串(或文章),请你找出所有四个数字连在一起的子串?
  2. 给你一个字符串(或文章),请你找出所有四个数字连在一起的的子串,并且这四个数字要满足:第一位与第四位相同,第二位与第三位相同,比如1221、5775
  3. 请验证输入的邮件,是否复合电子邮件格式
  4. 请验证输入的手机号,是否符合手机号格式

为了解决上述问题,Java提供了正则表达式技术,专门用于处理类似文本问题;简单地说:正则表达式是对字符串执行模式匹配的技术

3、正则表达式的基本介绍

一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为他们看上去比较古怪而且复杂所以所以不敢去用,不过,经过练习后,就觉得这些复杂的表达式看起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成。

注意:正则表达式并不是只有Java才有,实际上很多编程语言都支持正则表达式进行字符串操作!

4、正则表达式的底层实现(重要!!!)

(1)实例分析

给你一段字符串(文本),请找出所有四个数字连载一起的子串,比如:1998

不分组的情况:
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 分析Java的正则表达式的底层实现(重要!!!!)
 * @date 2024/5/25 15:37:03
 */
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 平台的企业版),应" +
                "用 3443 于基于 Java 的应用服务器。Java 2 平台的发布,是 Java 发展过程中最重要的一个" +
                "里程碑,标志着 Java 的应用开始普及 9889";
        //目标:匹配所有四个数字
        //1、建立正则表达式规则
        //说明:\\d 表示任意一个数字
        String regStr="\\d\\d\\d\\d";
        //2、创建模式对象[即正则表达式对象]
        Pattern pattern = Pattern.compile(regStr);
        //3、创建匹配器
        //说明:创建匹配器matcher,按照正则表达式规则去匹配content字符串
        Matcher matcher = pattern.matcher(content);

        //4、开始匹配
        /*
            matcher.find() 完成的任务
            1、根据指定的规则,定位满足规则的子字符串(比如1998)
            2、找到后,将子字符串的开始索引记录到matcher对象的属性 int[] groups;
                groups[0]=0, 把该子字符串的结束的索引+1的值记录到groups[1]=4
            3、同时记录oldLast的值为子字符串的结束的索引+1的值即35,及下次执行find时,就从4开始匹配

            matcher.group(0) 分析
            源码:
            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开始截取子字符串返回
                就是[0,4) 包含0但是不包含索引为4的位置

            如果再次指向find方法,仍然按上面的分析来执行

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

在这里插入图片描述

分组的情况:
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 分析Java的正则表达式的底层实现(重要!!!!)
 * @date 2024/5/25 15:37:03
 */
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 平台的企业版),应" +
                "用 3443 于基于 Java 的应用服务器。Java 2 平台的发布,是 Java 发展过程中最重要的一个" +
                "里程碑,标志着 Java 的应用开始普及 9889";
        //目标:匹配所有四个数字
        //1、建立正则表达式规则
        //说明:\\d 表示任意一个数字
        String regStr="(\\d\\d)(\\d\\d)";
        //2、创建模式对象[即正则表达式对象]
        Pattern pattern = Pattern.compile(regStr);
        //3、创建匹配器
        //说明:创建匹配器matcher,按照正则表达式规则去匹配content字符串
        Matcher matcher = pattern.matcher(content);

        //4、开始匹配
        /*
            matcher.find() 完成的任务(考虑分组的情况)
            什么是分组?比如(\d\d)(\d\d),正则表达式中有() 表示分组,第1个() 表示第一组,第2个() 表示第二组...
            1、根据指定的规则,定位满足规则的子字符串(比如(19)(98))
            2、找到后,将子字符串的开始索引记录到matcher对象的属性 int[] groups;
                2-1、groups[0]=0, 把该子字符串的结束的索引+1的值记录到groups[1]=4
                2-2、记录1组()匹配到的字符串 groups[2]=0 groups[3]=2
                2-3、记录2组()匹配到的字符串 groups[4]=2 groups[5]=4
                2-4、如果有更多的分组,以此类推...
            3、同时记录oldLast的值为子字符串的结束的索引+1的值即35,及下次执行find时,就从4开始匹配

            matcher.group(0) 分析
            源码:
            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开始截取子字符串返回
                就是[0,4) 包含0但是不包含索引为4的位置

            如果再次指向find方法,仍然按上面的分析来执行

         */
        while(matcher.find()){
            /*
                小结:
                1、如果正则表达式有() 及分组
                2、取出匹配的字符串规则如下
                3、group(0) 表示匹配到的子字符串
                4、group(1) 表示匹配到的子字符串的第一组字串
                5、group(2) 表示匹配到的子字符串的第二组字串
                6、。。。但是分组的数不能越界
             */
            System.out.println("找到:"+matcher.group(0));
            System.out.println("第一组()匹配到的值="+matcher.group(1));
            System.out.println("第二组()匹配到的值="+matcher.group(2));
        }
    }
}

在这里插入图片描述

在这里插入图片描述

5、正则表达式语法

(1)基本介绍

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

  • 限定符
  • 选择匹配符
  • 分组组合和反向引用符
  • 特殊字符
  • 字符匹配符
  • 定位符

(2)元字符Metacharacter–转义号 \\

在我们使用正则表达式去检索某些特殊字符的时候,需要用到转移符号,否则检索不到结果,甚至会报错。注意:在Java的正则表达式中,两个\代表其他语言中的一个\

package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示元字符-->转义号 \\的使用
 * @date 2024/5/25 22:09:08
 */
public class RegExp02 {
    /*
        步骤:
            1、建立规则 String regStr=" ";
            2、创建模式对象[正则表达式对象] Pattern pattern = Pattern.compile(regStr);
            3、创建匹配器 Matcher matcher = pattern.matcher(content);
            4、进行匹配
            while(matcher.find()){
                System.out.println("找到"+matcher.group(0));
            }
     */
    public static void main(String[] args) {
        String content="abc$(a.bc(123()";
        //匹配(   =>  \\(
        //String regStr="\\(";
        //匹配.   =>  \\.
        //String regStr="\\.";
        //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));
        }
        //需要用到转义字符的符号有以下:. * + ( ) $ / \ ? [ ] ^ { }
    }
}

(3)元字符–字符匹配符

符号含义示例解释匹配输入
[]可接受的字符列表[abc]a、b、c中任意一个
[^]不接受的字符列表[^abc]除a、b、c之外的任意一个字符,包括数字或特殊符号
-连字符A-Z任意单个大写字母
.匹配除\n以外的任何字符a…b以a开头,b结尾,中间包括2个任意字符的长度为4的字符串a12b,acdb,a&*b
\\d匹配单个字符,相当于[0-9]\\d{3}(\\d)?包含3个或4个数字的字符串123,1234
\\D匹配非数字字符,相当于[^0-9]\\D(\\d)*以单个非数字字符开头,后接任意个 数字字符串a,A123
\\w匹配单个数字、大小写字母字符,相当于[0-9a-zA-Z]\\d{3}\\w{4}以3个数字开头的长度为7的数字字母字符串123abcd,12345pe
\\W匹配单个非数字、大小写字母字符,相当于[^0-9a-zA-Z]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串#23,#?@22
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示字符匹配符的使用
 * @date 2024/5/26 10:21:26
 */
public class RegExp03 {
    public static void main(String[] args) {
        String content="a11c8abc_ABCy@.";
        //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]
        //String regStr="\\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)元字符–选择匹配符

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

符号含义示例解释
|匹配"|"之前或之后的表达式ab|cdab或者cd
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示选择匹配符
 * @date 2024/5/26 10:43:16
 */
public class RegExp04 {
    public static void main(String[] args) {
        String content="du 杜 Ghost-D";
        String regStr="du|杜|D";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            System.out.println("找到="+matcher.group(0));
        }
    }
}

(5)元字符–限定符

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

符号含义示例说明匹配输入
*指定字符重复0次或n次(无要求)零到多(abc)*仅包含任意个abc的字符串abc,abcabcabc
+指定字符重复1次或n次(至少1次)1到多m+(abc)*以至少1个m开头,后接任意个abc的字符串m,mabc,mmmabc
?指定字符重复0次或1次(最多1次)0到1m+abc?以至少1个m开头,后接ab或abc的字符串mab,mabc,mab,mmabc
{n}只能输入n个字符[abcd]{3}由abcd中字母组成的任意长度为3的字符串abc,dbc,adc
{n,}指定至少n个匹配[abcd]{3,}由abcd中字母组成的任意长度不小于3的字符串aab,dbc,aaaabbbc
{n,m}指定至少n个但不多于m个匹配[abcd]{3,5}由abcd中字母组成的任意长度不小于3,不大于5的字符串abc,abcd,aaaaa
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示限定符
 * @date 2024/5/26 10:49:03
 */
public class RegExp05 {
    public static void main(String[] args) {
        String content="a2111111aaaaaahello";
        //String regStr="a{3}";//匹配aaa
        //String regStr="1{4}";//匹配1111
        //String regStr="\\d{2}";//匹配两个任意数字字符

        /*
            细节:Java匹配默认贪婪匹配,即尽可能匹配多的
         */
        //String regStr="a{3,4}";//表示匹配aaa或者aaaa,他会先匹配有aaaa的
        //String regStr="\\d{2,5}";//表示匹配2位数或者3位数,4位数,5位数

        //1+
        //String regStr="1+";//匹配一个或多个1
        //String regStr="\\d+";//匹配一个或多个数字
        //1*
        //String regStr="1*";//匹配0个或者多个1

        //演示?的使用,遵循贪婪匹配
        String regStr="a2?";//匹配a或者a2


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

(6)元字符–定位符

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

符号含义示例说明匹配输入
^指定起始字符1+[a-z]*以至少一个数字开头,后接任意个小写字母的字符串123,6aa,555edf
$指定结束字符2\\-[a-z]+$以1个数字开头后接连字符"-",并以至少1个小写字母结尾的字符串1-a
\\b匹配目标字符串的边界Ghost\\b这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置123Ghost
\\B匹配目标字符串的非边界Ghost\\B和\\b相反Ghost-D
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示定位符的使用
 * @date 2024/5/26 17:42:29
 */
public class RegExp06 {
    public static void main(String[] args) {
        String content="hanshunping sphan nnhan";
        //String content="123-abc";
        //String regStr="^[0-9]+[a-z]*";//以至少1个数字开头,后接任意个小写字母的字符串
        //String regStr="^[0-9]+\\-[a-z]+$";//以至少1个数字开头,必须以至少一个小写字母结束
        //String regStr="han\\b";//表示匹配边界的han[这里的边界是指:被匹配的字符串最后,也可以是空格的子字符串的后面]
        String regStr="han\\B";//和\\b含义相反
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            System.out.println("找到="+matcher.group(0));
        }
    }
}

(7)分组

常用分组构造形式说明
(pattern)非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号
(?<name>pattern)命名捕获,将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如(?‘name’)
(?:pattern)匹配pattern但是不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储以后使用的匹配。者对于用"or"字符(|)组合模式部件的情况很有用。例如industr(?:y|ies)是比industry|industries更经济的表达式。
(?=pattern)它是一个非捕获匹配。例如windows(?=95|98|NT|2000)匹配"windows 2000"的windows,但是不匹配"windows 3.1"的windows
(?!pattern)该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配,例如例如windows(?!95|98|NT|2000)匹配"windows 3.1"的windows,但是不匹配"windows 2000"的windows。
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示分组的使用
 * @date 2024/5/26 17:53:11
 */
public class RegExp07 {
    public static void main(String[] args) {
        String content="hanshunping s7789 nn1189han";

        //下面是非命名分组
        /*
            说明:
            1、matcher.group(0) 得到匹配到的字符串
            2、matcher.group(1) 得到匹配到的字符串的第1个分组内容
            3、matcher.group(2) 得到匹配到的字符串的第2个分组内容
         */
        //String regStr="(\\d\\d)(\\d\\d)";//匹配4个数字的字符串

        //命名分组:即可以给分组取名
        String regStr="(?<g1>\\d\\d)(?<g2>\\d\\d)";//匹配4个数字的字符串
        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"));
        }
    }
}
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示非捕获分组,语法比较奇怪
 * @date 2024/5/26 20:54:57
 */
public class RegExp08 {
    public static void main(String[] args) {
        String content="hello 韩顺平教育 jack 韩顺平老师 韩顺平同学 hello 韩顺平学生";
        //找到韩顺平教育、韩顺平老师、韩顺平同学 子字符串
        //String regStr="韩顺平教育|韩顺平老师|韩顺平同学";
        //上面的写法可以等价非捕获分组,注意:不能matcher.group(1)
        //String regStr="韩顺平(?:教育|老师|同学)";

        //找到 韩顺平 这个关键字,但是要求只是查找韩顺平教育和韩顺平老师 中包含有的韩顺平
        //下面也是非捕获分组,不能使用matcher.group(1)
        //String regStr="韩顺平(?=教育|老师)";

        //找到 韩顺平 这个关键字,但是要求只是查找 不是 (韩顺平教育 和 韩顺平老师)中包含有的韩顺平
        //下面也是非捕获分组,不能使用matcher.group(1)
        String regStr="韩顺平(?!教育|老师)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            System.out.println(matcher.group(0));
        }
    }
}

6、应用实例

(1)对字符串进行如下验证

package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 应用实例
 * @date 2024/5/26 21:14:11
 */
public class RegExp10 {
    public static void main(String[] args) {
        String content="13588889999";
        //汉字
        //String regStr="^[\u0319-\uffe5]+$";

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

        //QQ号码 1、是1-9开头的一个(5位数-10位数) 比如 12389,1345687,187698765
        //String regStr="^[1-9]\\d{4,9}$";

        //手机号码 1、必须以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("不满足格式");
        }
    }
}
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/26 21:30:07
 */
public class RegExp11 {
    public static void main(String[] args) {
        String content="https://fanyi.baidu.com/mtpe-individual/multimodal#/";

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

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

7、正则表达式三个常用类

在这里插入图片描述

package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description 演示matches方法,用于整体匹配,在验证输入的字符串是否腕足条件使用
 * @date 2024/5/27 09:09:40
 */
public class PttternMethod {
    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);
    }
}
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description Matcher 类的常用方法
 * @date 2024/5/27 09:17:27
 */
public class MatcherMethod {
    public static void main(String[] args) {
        String content="hello edu jack hspedutom hello smith 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);
    }
}

8、分组,捕获,反向引用

(1)提出需求

给你一段文本,请找出所有四个数字连在一起的子串,并且这四个数字要满足第一位与第四位相同,第二位与第三位相同,比如1221

(2)介绍

  1. 分组

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

  1. 捕获

把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显示命名的组里,方便后面引用,从左往右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。组0代表的是整个正则式

  1. 反向引用

圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用\\分组号,外部反向引用$分组号

//匹配两个连续的相同的数字
String regStr="(\\d)\\1";
//匹配五个连续的相同的数字
String regStr="(\\d)\\1{4}";
//匹配个位与千位相同,十位与百位相同的数
String regStr="(\\d)(\\d)\\2\\1";

//满足前面是一个5位数,然后一个"-"号,然后是一个9位数,连续的每3位要相同 12321-333999111
String regStr="\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";
package regexp;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/27 09:32:55
 */
public class RegExp12 {
    /*
        要求:把: "我....我要....学学学学....编程 java!"
             通过正则表达式修改成"我要学编程 java"
     */
    public static void main(String[] args) {
        String content = "我....我要....学学学学....编程 java!";
        //第一步:去除.
        String regStr = "\\.";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        content = matcher.replaceAll("");
        //System.out.println("content="+content);
//        //第二步:去除重复字
//        pattern=Pattern.compile("(.)\\1+");
//        matcher=pattern.matcher(content);
//        while(matcher.find()){
//            System.out.println("找到="+matcher.group(0));
//        }
//        //使用反向引用$1来替换匹配到的内容
//        content=matcher.replaceAll("$1");
//        System.out.println("content="+content);

        content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
        System.out.println(content);
    }
}

9、String类中使用正则表达式

(1)替换功能

(2)判断功能

(3)分割功能

package regexp;

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/27 09:52:26
 */
public class StringReg {
    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);

        //要求 验证一个手机号,要求必须是以138 139开头的
        content="13888889999";
        if (content.matches("1(38|39)\\d{8}")){
            System.out.println("验证成功");
        }else {
            System.out.println("验证失败");
        }

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

10、本章作业

1、

在这里插入图片描述

package regexp.homework;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/27 20:48:55
 */
public class homework01 {
    public static void main(String[] args) {
        String content="2479970653@qq.com";
        String regStr="^([\\w_-]+)@([a-zA-Z.]+)$";

        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        if (matcher.matches()){
            System.out.println("匹配成功");
        }else {
            System.out.println("匹配失败");
        }
    }
}

2、

package regexp.homework;

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/27 20:49:03
 */
public class homework02 {
    public static void main(String[] args) {
        String content="123.015";
        String regStr="^[+|-]?([1-9]\\d*|0)(\\.\\d+)?$";
        if (content.matches(regStr)){
            System.out.println("匹配成功");
        }else {
            System.out.println("匹配失败");
        }
    }
}

3、

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

package regexp.homework;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/28 08:54:28
 */
public class homework03 {
    public static void main(String[] args) {
        String content="https://www.baidu.com:8080/index.html";
        String regStr="^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*/([\\w.]+)$";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        if (matcher.matches()){
            System.out.println("匹配成功");
        }else {
            System.out.println("匹配失败");
        }
    }
}
 if (content.matches(regStr)){
        System.out.println("匹配成功");
    }else {
        System.out.println("匹配失败");
    }
}

}


### 3、

[外链图片转存中...(img-PmutKqme-1716966962743)]

```java
package regexp.homework;

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

/**
 * @author D
 * @version 1.0
 * @project regular_expression
 * @description
 * @date 2024/5/28 08:54:28
 */
public class homework03 {
    public static void main(String[] args) {
        String content="https://www.baidu.com:8080/index.html";
        String regStr="^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*/([\\w.]+)$";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);

        if (matcher.matches()){
            System.out.println("匹配成功");
        }else {
            System.out.println("匹配失败");
        }
    }
}

  1. 0-9 ↩︎

  2. 0-9 ↩︎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值