Java正则表达式学习笔记(一)

本文详细介绍了Java中的正则表达式,包括正则表达式的概念、代码实现(不考虑和考虑分组)、元字符的使用,如转义符、字符匹配符、选择匹配符、限定符和定位符。同时讲解了分组的概念,包括常见分组和非捕获分组,并展示了非贪婪匹配的示例。内容涵盖了正则表达式的语法和实际操作,有助于理解Java中字符串的处理和匹配方法。
摘要由CSDN通过智能技术生成

一:正则表达式

1.1 正则表达式的介绍:

  • 一个正则表达式,就是用某种模式去匹配字符串的一个公式。(处理文本)
  • 正则表达式不是只有Java才有,实际上很多编程语言都支持正则表达式进行字符串操作。

 1.2 正则表达式的代码实现(不考虑分组):

package regexp;

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

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的应用服务器。9889Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。3443";

        //目标:匹配所有四个数字
        //说明:

        //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的值即4,即下次执行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();
        }

        当matcher.group(int group)中的参数为0时,根据groups[0]=0和groups[1]=4的记录的位置,从content开始截取子字符串返回,就是[0,4)---包含索引开始,不包含索引结尾
         */


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

    }
}

1.3 正则表达式的代码实现(考虑分组):

package regexp;

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

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的应用服务器。9889Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。3443";

        //目标:匹配所有四个数字
        //说明:

        //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. 根据指定的规则,定位满足规则的子字符串(比如(19)(98))
        2. 找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups
          2.1 groups[0]=0,把该子字符串的结束的索引+1的值记录到groups[1]=4
          2.2 记录一组()匹配到的字符串groups[2]=0 groups[3]=2
          2.3 记录二组()匹配到的字符串groups[2]=2 groups[3]=4
          2.4 有更多的分组,依次类推


        3.同时记录oldLast的值为子字符串的结束的索引+1的值即4,即下次执行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();
        }

        当matcher.group(int group)中的参数为0时,根据groups[0]=0和groups[1]=4的记录的位置,从content开始截取子字符串返回,就是[0,4)---包含索引开始,不包含索引结尾
         */


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

    }
}

二:正则表达式的语法

2.1 基本介绍:

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

  1. 限定符
  2. 选择匹配符
  3. 分组组合和反向引用符
  4. 特殊字符
  5. 字符匹配符
  6. 定位符

2.2 元字符(Metacharacter)

2.2.1 元字符-转义符 \\:

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

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

package regexp;

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

public class RegEcp02 {
    public static void main(String[] args) {
       String content="abc$(abc(123(";
       //匹配(
        String regStr="\\(";  //需要使用转义字符
        Pattern pattern=Pattern.compile(regStr);
        Matcher matcher=pattern.matcher(content);

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

2.2.2 元字符-字符匹配符:


字符匹配符的应用实例:

1. [a-z]说明:[a-z]表示可以匹配a-z中任意一个字符。

2.Java正则表达式默认是区分字母大小写的,如何实现不区分大小写

  • (?i)abc表示abc都不区分大小写
  • a(?i)bc表示bc不区分大小写
  • a((?i)b)c表示只有b不区分大小写
  • Pattern pattern=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);

3.[^a-z]说明:[^a-z]表示可以匹配不是a-z中的任意一个字符

4.\\d表示可以匹配0-9的任意一个数字,相当于[0-9]

5.\\D表示可以匹配不是0-9中的任意一个数,相当于[^0-9]

6.\\w匹配任意英文字符,数字和下划线,相当于[a-zA-Z0-9]

7.\\W相当于[^a-zA-Z0-9]是\w刚好相反

8.\\s匹配任何空白字符(空格、制表符等)

9.\\S匹配任何非空白字符,和\s刚好相反

10.  (.)匹配出\n之外的所有字符,如果要匹配,本身则需要使用\\

package regexp;

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

public class RegExp03 {
    public static void main(String[] args) {
        String content="a11c8abcABC";
        /*
        java正则表达式默认区分大小写
         */
        //String regStr="[a-z]";//1.匹配到a-z任意一个字符
        //String regStr="[A-Z]";//2.匹配到A-Z任意一个字符
        //String regStr="(?i)abc";//3.匹配abc字符串【不区分大小写】
        String regStr="[^a-z]{2}";//5.匹配不在a-z之间任意一个字符

        Pattern pattern=Pattern.compile(regStr);

        //4.当创建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));
        }
    }
}

2.2.3 元字符-选择匹配符:

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

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

public class RegExp04 {
    public static void main(String[] args) {
        /*
        选择匹配符
         */
        String content="周 jia  jiaX 1221321abc zhou ABC";
        String RegStr="周|zhou";
        Pattern pattern=Pattern.compile(RegStr);
        Matcher matcher=pattern.matcher(content);
        while (matcher.find()){
            System.out.println("找到 "+matcher.group(0));
        }
    }
}

2.2.3 元字符-限定符:

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

 注意:Java匹配默认贪婪匹配,即尽可能匹配多的

例如:"a{3,4}",Java优先匹配aaaa,然后匹配aaa

2.2.4 元字符-定位符:

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

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

public class RegExp05 {
    public static void main(String[] args) {
                /*
        定位符
         */
        // String content = "123周 123jia  jiaX 122zhou1321abc zhou ABC abcabc123abc  123zhou";
        String content = "123zhouabczhou 123zhou";
        //  String RegStr = "^[0-9]+[a-z]*";//以至少一个数字开头(字符串的开头),后接任意个小写字母的字符串
        //  String RegStr = "^[0-9]+[a-z]+$"; //以至少一个数字开头,必须以至少一个小写字母结束

        //String RegStr="zhou\\b";  //表示匹配边界的zhou[这里的边界是指:被匹配的字符串最后],也可以是空格的字符串的后面
        String RegStr="zhou\\B";  //表示匹配非边界的zhou
        Pattern pattern = Pattern.compile(RegStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到 " + matcher.group(0));
        }
    }
}

2.3 分组:

2.3.1:常见分组:

package regexp;

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

public class RegExp06 {
    /*
    分组
     */
    public static void main(String[] args) {
        String content="abc1234def5678";

        //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("第一个分组内容="+matcher.group(1));//得到匹配到的字符串的第一个分组内容
            System.out.println("第二个分组内容="+matcher.group(2));//得到匹配到的字符串的第二个分组内容
        }

         */
        while (matcher.find()){
            System.out.println("找到="+matcher.group(0));
            System.out.println("第一个分组内容[通过分组]="+matcher.group("g1"));
            System.out.println("第二个分组内容[通过分组]="+matcher.group("g2"));
        }
    }
}

2.3.2 :特别分组:(非捕获分组)

package regexp;

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

public class RegExp07 {
    /*
    非捕获分组
     */
    public static void main(String[] args) {
        String content="zjx教育,zjx老师,zjx同学";

       // String RegStr="zjx教育|zjx老师|zjx同学";

        //上面写法可以等价非捕获分组,注意:不能 matcher.group(1)
     //   String RegStr="zjx(?:教育|老师|同学)";

        //找到zjx这个关键字,但是要求只是找到zjx教育和zjx老师中的zjx
        //String RegStr="zjx(?=教育|老师)";
        String RegStr="zjx(?!同学)";   //取反,也可以的到这样的结果


        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));  //这里会报错,因为是非捕获分组
        }

         */

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

2.4 非贪婪匹配:

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

public class RegExp08 {
    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));
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值