正则表达式底层实现

27
五月
2021

一、正则表达式底层实现(不分组)

package com.jun.regexp;

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

/**
 * 正则表达式底层实现
 */
public class RegTheory {
    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的计算能力有了大幅提升,与J2SE1.3相比,其多了近62%的类和接口。" +
                "在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。" +
                "2004年9月30日,J2SE1.5发布,成为Java语言发展史上的又一里程碑。" +
                "为了表示该版本的重要性,J2SE 1.5更名为Java SE 5.0(内部版本号1.5.0),代号为“Tiger”,Tiger包含了从1996年发布1.0版本以来的最重大的更新," +
                "其中包括泛型支持、基本类型的自动装箱、改进的循环、枚举类型、格式化I/O及可变参数。";
        //匹配所有四个数字
        String regStr = "(\\d\\d)(\\d\\d)";
        //创建模式对象
        Pattern pattern = Pattern.compile(regStr);
        //创建匹配器
        //创建匹配器matcher,按照正则表达式的规则去匹配content字符串
        Matcher matcher = pattern.matcher(content);
        //开始匹配
        /**
         * matcher.find()完成任务
         * 1.根据指定的规则,找到满足规则的子字符串(比如2000)
         * 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();
         *     }
         *     根据groups[0]=0 和 groups[1] =4 的记录的位置,从content开始截取子字符串返回
         *     就是[0,4) 包含0但不包含索引为4的位置
         *   假如再次指向find方法,仍然按上面方法执行
         */
        while (matcher.find()){
            System.out.println("找到:"+matcher.group(0));
        }

    }
}

 二·、正则表达式底层实现(分组)

package com.jun.regexp;

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

/**
 * 正则表达式底层实现
 */
public class RegTheory {
    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的计算能力有了大幅提升,与J2SE1.3相比,其多了近62%的类和接口。" +
                "在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。" +
                "2004年9月30日,J2SE1.5发布,成为Java语言发展史上的又一里程碑。" +
                "为了表示该版本的重要性,J2SE 1.5更名为Java SE 5.0(内部版本号1.5.0),代号为“Tiger”,Tiger包含了从1996年发布1.0版本以来的最重大的更新," +
                "其中包括泛型支持、基本类型的自动装箱、改进的循环、枚举类型、格式化I/O及可变参数。";
        //匹配所有四个数字
        String regStr = "(\\d\\d)(\\d\\d)";
        //创建模式对象
        Pattern pattern = Pattern.compile(regStr);
        //创建匹配器
        //创建匹配器matcher,按照正则表达式的规则去匹配content字符串
        Matcher matcher = pattern.matcher(content);
        //开始匹配
        /**
         * matcher.find()完成任务()(分组)
         * 分组:(\\d\\d)(\\d\\d),正则表达式中有()表示分组,一个括号表示一组
         * 1.根据指定的规则,找到满足f规则的子字符串(比如(20)(00))
         * 2.找到后,将子字符串的开始索引记录到matcher对象属性 int[] groups;
         *   groups[0]=0,把该字符串的结束的索引+1的值记录到groups[1]=4
         *   记录1组()匹配到的字符串groups[2]=0,groups[3]=2
         *   记录2组()匹配到的字符串groups[4]=2,groups[5]=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();
         *     }
         *     根据groups[0]=0 和 groups[1] =4 的记录的位置,从content开始截取子字符串返回
         *     就是[0,4) 包含0但不包含索引为4的位置
         *   假如再次指向find方法,仍然按上面方法执行
         */
        while (matcher.find()){
            /**
             * 正则表达式有()就是分组
             * 取出匹配规则如下;
             * group(0) 表示匹配到的子字符串
             * group(1) 表示匹配到的子字符串的第一组字串
             * group(2) 表示匹配到的子字符串的第二组字串
             * ....但分组不能越界
             */
            System.out.println("找到:"+matcher.group(0));
            System.out.println("第一组匹配到:"+matcher.group(1));
            System.out.println("第二组匹配到:"+matcher.group(2));
        }

    }
}

 

TAG

网友评论

共有访客发表了评论
请登录后再发布评论,和谐社会,请文明发言,谢谢合作! 立即登录 注册会员