首页 > 其他分享 >正则表达式底层实现

正则表达式底层实现

时间:2024-01-29 22:35:24浏览次数:30  
标签:group 正则表达式 matcher content 实现 groups 字符串 匹配 底层

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的计算能力有了大幅提升,与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及可变参数。";

    // \\d代表一个任意的数字,这段正则匹配的是一个四位的数字
    String regStr = "\\d\\d\\d\\d";
    // 创建模式对象,即正则表达式对象
    Pattern pattern = Pattern.compile(regStr);
	// 创建匹配器,按照正则表达式的规则匹配content字符串
    Matcher matcher = pattern.matcher(content);

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

代码解析

①、matcher.find()

  1. 根据指定的规则,定位满足规则的子字符串(比如content中的第一个匹配结果2000)

  2. 找到后,将子字符串的开始、结束索引记录到matcher对象的属性 int[] groups 中

    groups[0] = 0; 记录的为子字符串开始索引

    groups[1] = 4; 记录的为子字符串结束索引 + 1

  3. 同时记录oldLast的值为子字符串结束索引 + 1,下次执行matcher.find()时,就从oldLast开始匹配

②、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的值

2、考虑分组

什么是分组,比如 (\d\d)(\d\d),正则表达式中有(),表示分组,第1个()表示第1组,第2个()表示第2组

代码示例

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

代码解析

①、matcher.find()

  1. 根据指定的规则,定位满足规则的子字符串(比如content中的第一个匹配结果2000)

  2. 找到后,将子字符串的开始、结束索引记录到matcher对象的属性 int[] groups 中

    1. groups[0] = 0; 记录的为子字符串开始索引 groups[1] = 4; 记录的为子字符串结束索引 + 1
    2. 记录第1组()匹配到的字符串groups[2] = 0; groups[3] = 2;
    3. 记录第2组()匹配到的字符串groups[4] = 2; groups[5] = 4;
    4. 更多的分组......
  3. 同时记录oldLast的值为子字符串结束索引 + 1,下次执行matcher.find()时,就从oldLast开始匹配

②、matcher.group()

  1. group(0):表示匹配到的子字符串
  2. group(1):表示匹配到的子字符串的第1组子串
  3. group(2):表示匹配到的子字符串的第2组子串
  4. 更多的分组......

标签:group,正则表达式,matcher,content,实现,groups,字符串,匹配,底层
From: https://www.cnblogs.com/duya12345/p/17995504

相关文章

  • python自定义装饰器,实现轮询监控数据库,并且根据字段内容变更打印相应日志或结束循环
    使用方法可以写个whileTrue的循环监控数据,再分别定义每个状态要做什么事情注意:循环中不要写breake不要return,换成yield,把函数作为一个生成器,由装饰器控制循环代码示例importfunctoolsimporttimefromutils.log_settingimportloggerfromconfigimportsetti......
  • 为啥一样一样的正则表达式,去提取就提取不出来?
    大家好,我是皮皮。一、前言前几天在Python最强王者交流群【哎呦喂 是豆子~】问了一个Pandas数据提取的问题。问题如下图所示:大佬们  为啥一样一样的正则表达式 for循环就可以出结果用apply(lambdax:re.findall(pattern,x))去提取就提取不出来?图一:图二:二、实现过......
  • # yyds干货盘点 # 为啥一样一样的正则表达式,去提取就提取不出来?
    大家好,我是皮皮。一、前言前几天在Python最强王者交流群【哎呦喂 是豆子~】问了一个Pandas数据提取的问题。问题如下图所示:大佬们  为啥一样一样的正则表达式 for循环就可以出结果用apply(lambdax:re.findall(pattern,x))去提取就提取不出来?图一:图二:二、实现过程这里【隔......
  • 优雅的实现接口防刷,最强方案来了~!
    1前言本文为描述通过Interceptor以及Redis实现接口访问防刷Demo这里会通过逐步找问题,逐步去完善的形式展示2原理通过ip地址+uri拼接用以作为访问者访问接口区分通过在Interceptor中拦截请求,从Redis中统计用户访问接口次数从而达到接口防刷目的如下图所示3工程其中,Interceptor处代码......
  • 普锐特冶金技术硅钢轧机助蒂森克虏伯实现高质量生产
    此前,普锐特冶金技术为德国钢铁企业蒂森克虏伯钢铁公司提供的双机架可逆式冷轧机生产出了第一个带卷。这是世界首套采用先进的HyperUCM技术生产硅钢的双机架可逆式冷轧机,蒂森克虏伯钢铁公司将生产汽车和电动汽车电机使用的高硬度和薄规格板带,产量与单机架轧机相比大幅提高。......
  • hashmap线程不安全 ConcurrentHashMap是如何实现线程安全的
       2、JDK1.8中的数据覆盖(1)dk1.7的数据丢失、死循环问题在JDK1.8中已经得到了很好的解决,直接在HashMap的resize()中完成了数据迁移。(2)为什么说JDK1.8会出现数据覆盖的情况?查看这段JDK1.8中的put操作代码:在这里插入图片描述如下图框中的代码是判断是否出现hash碰撞,假设两个......
  • celery实现异步任务、定时任务和延迟任务
    1.异步任务任务名.delay(传参数)2.延迟任务fromdatetimeimportdatetime,timedelta#atetime.utcnow()当前utc时间#当前时间+15秒eta=datetime.utcnow()+timedelta(seconds=15)#取消订单任务res=cancel_order.apply_async(args=['10001',],eta=eta)#15s......
  • Eventgrid+Function实现event driven架构 - 架构介绍及环境部署
    今天来介绍这几年在云上比较流行的eventdriven,也就是事件驱动的架构,用一个很简单的sample来实际看下事件驱动的架构到底是个啥事件驱动的架构由生成事件流的事件生成者和侦听事件的事件使用者组成,它的特点是事件可几乎实时发送,因此使用者可在事件发生时需要立即做出响应。生成者......
  • 百度飞桨paddle paddle实现蝴蝶分类
    一、实验背景近年来,随着人工智能的发展,其在语音识别、自然语言处理、图像与视频分析等诸多领域取得了巨大成功。如何将人工智能技术应用到更广泛的领域成为了重要目标,本次竞赛将聚焦蝴蝶图片的细粒度图像分类,利用人工智能技术,对蝴蝶的类别、属性进行识别分类,以便相关工作者快速识别......
  • Hugging Face创始人分享:企业如何在ChatGPT浪潮下实现战略布局
    HuggingFace创始人兼首席执行官ClemDelangue在IBM一年一度的THINK大会中研讨了当前人工智能发展趋势,特别是ChatGPT模型以及其对行业的影响。他的演讲还涉及到一个关键的议题,在ChatGPT这样的通用模型出现后,企业如何在人工智能领域找到自己的定位与价值。他的观点不仅深刻反映了......