JAVA字符串与正则表达式

embedded/2025/3/16 5:20:14/

文章目录

  • 写在前面
    • 1、String
      • 1.1、String底层实现
      • 1.2、str="abc"和new String("abc")的区别
      • 1.3、使用+拼接字符串
      • 1.4、如何使用String.intern节约内存
      • 1.5、分割字符,split()和indexOf()用哪个
    • 2、正则表达式
      • 2.1、DFA和NFA
      • 2.2、怎么减少回溯?

写在前面

1、String在java源码中是怎么实现的?
2、什么是正则表达式的DFA自动机和NFA自动机?

1、String

1.1、String底层实现

Java 6及以前版本,通过char数组,每个char占用两个字节,使得String能够很好地处理Unicode。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {  private final char[] value;  private int offset;  private int count;  // ...其他成员和方法  
}  

Java 7至Java 8版本,offset和count两个变量被移除,String.substring不再共享char[],解决内存可能泄漏问题。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {  private final char[] value;  // ...其他成员和方法  
}  

Java9开始,把char[]改成了byte[] + coder(编码标识)

1.2、str="abc"和new String(“abc”)的区别

  • str=“abc”
    会先检查"abc"在不在常量池,在就不创建了,直接拿引用
  • new String(“abc”)
    先将”abc“放入常量池,再将其引用传给new的String

1.3、使用+拼接字符串

使用+拼接字符串,代码编译后,会被替换成StringBuilder。并且每+的一个字符串都可能被new一个新的StringBuilder,所以建议少用+,直接用StringBuilder

1.4、如何使用String.intern节约内存

String a = new String(“a123”).intern();
当调用intern()时,会先查看常量池中是否已有字符串”a123“, 所以当多次用到”a123“时,使用String.intern不会再创建新的字符串,从而节约内存。

1.5、分割字符,split()和indexOf()用哪个

split()使用正则表达式实现,正则表达式性能是比较不稳定的。
indexOf()能分割时尽量用indexOf()

2、正则表达式

2.1、DFA和NFA

正则表达式引擎构造代价执行效率优势
NFA支持更多,如group、环视、占有有限量词
DFA

NFA 自动机回溯

str = "arrrc"
reg = "ar{1,3}c"自动回溯会先匹配arrr,匹配到c,发现不是r,就回溯到最后一个r,用reg的c去继续匹配

2.2、怎么减少回溯?

1、贪婪模式
如上述例子就是贪婪模式
2、懒惰模式

str = "arrrc"
reg = "ar{1,3}?c"懒惰模式会先匹配ar,发现已经有一个r了,就开始用c接着匹配

3、独占模式

str = "arrc"
reg = "ar{1,3}+rc"独占模式会先匹配ar,发现已经有一个r了,就开始用rc接着匹配,不会回溯

下面这种独占模式会回溯

str = "arrc"
reg = "ar{1,3}+c"独占模式会先匹配ar,发现已经有一个r了,就开始用c接着匹配,匹配失败回溯

总结:
1、少用贪婪模式,多用独占模式
2、减少分支选择,如将”(abcd|abef)“替换为”ab(cd|ef)“
3、减少捕获嵌套。
捕获组: 一个 ()里面的就是一个不获取
非捕获组:一个(?:EXP)就是一个非捕获组

str = "<input id=1>文本</input>"
reg = "(<input.*?)(.*?)(</input)"
# 上面reg包含了3个捕获组,所以如果输出捕获结果会有整个匹配到的内容+括号里面的,4组字符串str = "<input id=1>文本</input>"
reg = "(?:<input.*?)(.*?)(?:</input)"
# 上面reg包含了1个捕获组,所以如果输出捕获结果会有整个匹配到的内容+捕获组括号里面的,2组字符串

http://www.ppmy.cn/embedded/172972.html

相关文章

微店平台商品关键字搜索接口调用指南:Python代码实现与实战解析

一、接口概述 微店开放平台提供商品搜索API接口&#xff0c;支持通过关键字检索店铺商品信息。本接口采用RESTful风格设计&#xff0c;支持OAuth2.0认证&#xff0c;返回标准JSON格式数据。 获取key和secret 二、准备工作 注册微店开放平台开发者账号 创建应用并获取以下凭证…

《C#上位机开发从门外到门内》2-5:USB通信

文章目录 一、引言二、USB通信概述2.1 USB基本原理2.2 USB协议栈与数据传输流程 三、USB通信模式详解3.1 HID通信模式3.1.1 HID简介3.1.2 工作原理与数据结构3.1.3 应用场景 3.2 CDC通信模式3.2.1 CDC简介3.2.2 工作原理与数据传输3.2.3 应用场景 3.3 Bulk传输模式3.3.1 Bulk传…

FPGA初级项目10——基于SPI的DAC芯片进行数模转换

FPGA初级项目10——基于SPI的DAC芯片进行数模转换 DAC芯片介绍 DAC 芯片&#xff08;数字模拟转换器&#xff09;是一种将数字信号转换为连续模拟信号&#xff08;如电压或电流&#xff09;的集成电路&#xff0c;广泛应用于电子系统中&#xff0c;连接数字世界与模拟世界。 …

大语言模型微调和大语言模型应用的区别?

1. 基本概念 微调&#xff08;Fine-tuning&#xff09; 定义&#xff1a;微调是指在预训练大语言模型的基础上&#xff0c;通过在特定领域或任务的数据上进一步训练&#xff0c;从而使模型在该特定任务上表现更优。 目的&#xff1a;适应具体的任务需求&#xff0c;比如法律文…

Linux——信号

前言&#xff1a;信号和信号量没有任何关系 操作系统开机即处于死循环状态&#xff0c;直到给操作系统发送信号时&#xff0c;才会开始执行相应操作。 1. 信号的产生 给进程产生信号的信号源是非常多的&#xff01; 1.1 键盘产生信号 打开VS&#xff0c;运行一个进程&#…

虚拟展览馆小程序:数字艺术与文化展示的新形式探索

虚拟展览馆小程序:数字艺术与文化展示的新形式探索 一、传统展览的痛点:物理空间的局限与数字化的必然 在传统的艺术与文化展览中,观众往往需要跨越地理距离、排队数小时才能进入展馆,而许多珍贵展品因保护需求无法长期展出。数据显示,全球90%以上的博物馆藏品常年沉睡于…

图像分类数据集

《动手学深度学习》-3.5-学习笔记 # 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式&#xff0c; # 并除以255使得所有像素的数值均在0&#xff5e;1之间 trans transforms.ToTensor()#用于将图像数据从 PIL 图像格式&#xff08;Python Imaging Library&#xff…

Spring Boot与Apache Ignite集成:构建高性能分布式缓存和计算平台

1. 前言 1.1 什么是Apache Ignite Apache Ignite是一个高性能的分布式内存计算平台,支持内存缓存、分布式计算、流处理和机器学习等功能。它提供了低延迟的数据访问和强大的计算能力,适用于需要高性能和可扩展性的应用。 1.2 为什么选择Apache Ignite 高性能:Ignite利用内…