如何掌握 Java 正则表达式 的基本语法及在 Java 中的应用
正则表达式是一种用于匹配字符串的模式,在许多编程语言中广泛使用。Java 正则表达式提供了强大的文本处理能力,能够对字符串进行查找、替换、分割等操作。
一、正则表达式的基本语法
正则表达式由普通字符和特殊字符组成。普通字符包括字母、数字和标点符号,而特殊字符(也称为元字符)则具有特殊意义,用于构建复杂的匹配模式。
1.1 普通字符
普通字符匹配自身。例如,正则表达式 abc
匹配字符串 "abc"
。
1.2 元字符
元字符是正则表达式的核心部分,用于定义复杂的匹配模式。常见的元字符包括:
.
:匹配任意一个字符(除换行符)。^
:匹配字符串的开始。$
:匹配字符串的结束。*
:匹配前一个字符零次或多次。+
:匹配前一个字符一次或多次。?
:匹配前一个字符零次或一次。[]
:定义字符类,匹配其中任意一个字符。|
:表示“或”操作。()
:用于分组和捕获。{}
:用于限定重复次数。
1.3 转义字符
有些字符在正则表达式中有特殊意义,如果要匹配这些字符本身,需要使用反斜杠 \
进行转义。例如,要匹配字符 .
,应使用 \.
。
1.4 字符类
字符类用于定义一个字符集合,匹配其中任意一个字符。常用的字符类包括:
[abc]
:匹配字符a
、b
或c
。[a-z]
:匹配任意一个小写字母。[A-Z]
:匹配任意一个大写字母。[0-9]
:匹配任意一个数字。[^abc]
:匹配除a
、b
、c
之外的任意一个字符。
1.5 预定义字符类
预定义字符类是一些常用字符类的简写形式,包括:
\d
:匹配一个数字,等价于[0-9]
。\D
:匹配一个非数字字符,等价于[^0-9]
。\w
:匹配一个单词字符(字母、数字或下划线),等价于[a-zA-Z0-9_]
。\W
:匹配一个非单词字符,等价于[^a-zA-Z0-9_]
。\s
:匹配一个空白字符(空格、制表符、换行符等),等价于[ \t\n\x0B\f\r]
。\S
:匹配一个非空白字符,等价于[^ \t\n\x0B\f\r]
。
1.6 边界匹配符
边界匹配符用于匹配字符串中的边界位置,包括:
\b
:匹配一个单词边界。\B
:匹配一个非单词边界。
1.7 限定符
限定符用于指定前一个字符或子模式的重复次数,包括:
*
:匹配前一个字符零次或多次。+
:匹配前一个字符一次或多次。?
:匹配前一个字符零次或一次。{n}
:匹配前一个字符恰好 n 次。{n,}
:匹配前一个字符至少 n 次。{n,m}
:匹配前一个字符至少 n 次,至多 m 次。
1.8 捕获组和非捕获组
捕获组用于将匹配的子模式存储起来,以便在后续操作中引用。非捕获组用于对子模式进行分组,但不存储匹配结果。
()
:捕获组。(?:)
:非捕获组。
1.9 零宽断言
零宽断言用于指定某个位置必须满足的条件,包括:
(?=)
:正向先行断言。(?!
:负向先行断言。(?<=)
:正向后行断言。(?<!
:负向后行断言。
二、Java 中的正则表达式 API
Java 提供了 java.util.regex
包来支持正则表达式处理,其中最重要的类是 Pattern
和 Matcher
。
2.1 Pattern
类
Pattern
类表示一个正则表达式的编译表示。常用的方法包括:
compile(String regex)
:编译给定的正则表达式。matcher(CharSequence input)
:创建一个匹配器对象。
2.2 Matcher
类
Matcher
类用于对输入字符串进行模式匹配操作。常用的方法包括:
matches()
:整个字符串是否与正则表达式匹配。find()
:是否找到与正则表达式匹配的子字符串。group()
:返回前一次匹配的子字符串。replaceAll(String replacement)
:替换所有匹配的子字符串。replaceFirst(String replacement)
:替换第一个匹配的子字符串。lookingAt()
:是否从字符串的开头开始匹配。
三、Java 正则表达式的常见用法
3.1 字符串匹配
3.1.1 完全匹配
要判断字符串是否完全匹配某个正则表达式,可以使用 Pattern
和 Matcher
类:
String regex = "\\d+";
String input = "12345";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
boolean isMatch = matcher.matches();
System.out.println("完全匹配: " + isMatch);
3.1.2 子字符串匹配
要判断字符串中是否包含某个正则表达式匹配的子字符串,可以使用 find
方法:
String regex = "\\d+";
String input = "hello 12345 world";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
boolean found = matcher.find();
System.out.println("包含子字符串匹配: " + found);
3.2 字符串替换
正则表达式可以用于替换字符串中的匹配部分。replaceAll
和 replaceFirst
方法用于替换所有匹配的子字符串或第一个匹配的子字符串:
String regex = "\\d+";
String input = "hello 12345 world";
String replacement = "number";
String result = input.replaceAll(regex, replacement);
System.out.println("替换结果: " + result);
3.3 字符串分割
正则表达式可以用于根据模式分割字符串。String
类提供了 split
方法:
String regex = "\\s+";
String input = "hello world java";
String[] parts = input.split(regex);
System.out.println("分割结果: " + Arrays.toString(parts));
3.4 捕获组
捕获组用于将匹配的子模式存储起来,以便在后续操作中引用。可以使用 group
方法获取捕获组的内容:
String regex = "(\\d{3})-(\\d{2})-(\\d{4})";
String input = "123-45-6789";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {String part1 = matcher.group(1);String part2 = matcher.group(2);String part3 = matcher.group(3);System.out.println("捕获组: " + part1 + ", " + part2 + ", " + part3);
}
3.5 零宽断言
零宽断言用于指定某个位置必须满足的条件,但不包括在匹配结果中。以下示例展示了正向先行断言:
String regex = "foo(?=bar)";
String input = "foobar";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {System.out.println("零宽断言匹配: " + matcher.group());
}
四、Java 正则表达式高级应用
4.1 动态构建正则表达式
有时我们需要根据不同的输入动态构建正则表达式。可以使用 StringBuilder
来拼接正则表达式:
String basePattern = "\\d";
int minDigits = 2;
int maxDigits = 4;
StringBuilder regex = new StringBuilder(basePattern);
regex.append("{").append(minDigits).append(",").append(maxDigits).append("}");
Pattern pattern = Pattern.compile(regex.toString());
String input = "123";
Matcher matcher = pattern.matcher(input);
boolean isMatch = matcher.matches();
System.out.println("动态构建正则表达式匹配: " + isMatch);
4.2 正则表达式中的嵌套组
嵌套组用于在一个捕获组内再嵌套另一个捕获组,以下示例展示了嵌套组的用法:
String regex = "(\\d{2})((\\d{2}))";
String input = "1234";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {String outerGroup = matcher.group(1);String nestedGroup = matcher.group(2);String innermostGroup = matcher.group(3);System.out.println("外部组: " + outerGroup + ", 嵌套组: " + nestedGroup + ", 最内部组: " + innermostGroup);
}
4.3 分组命名和引用
Java 7 引入了分组命名功能,可以给捕获组命名,并通过名字引用:
String regex = "(?<areaCode>\\d{3})-(?<prefix>\\d{3})-(?<lineNumber>\\d{4})";
String input = "123-456-7890";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {String areaCode = matcher.group("areaCode");String prefix = matcher.group("prefix");String lineNumber = matcher.group("lineNumber");System.out.println("命名捕获组: " + areaCode + ", " + prefix + ", " + lineNumber);
}
4.4 正则表达式的性能优化
在处理大型文本或复杂模式时,正则表达式的性能可能成为瓶颈。以下是一些性能优化建议:
- 避免回溯:尽量避免使用可能导致大量回溯的模式,如重复的捕获组。
- 预编译正则表达式:将正则表达式编译为
Pattern
对象,并重用该对象,而不是每次都重新编译。 - 使用非捕获组:在不需要捕获匹配内容时,使用非捕获组
(?:)
代替捕获组()
。
4.5 正则表达式调试
调试正则表达式可能比较困难,可以使用在线工具(如 regex101)或集成开发环境(IDE)中的正则表达式调试功能来帮助理解和测试正则表达式。
掌握正则表达式可以大大提高文本处理的效率和灵活性,Java 提供的正则表达式 API 使得在程序中使用正则表达式变得简单高效。
黑马程序员免费预约咨询
相关文章:

如何掌握 Java 正则表达式 的基本语法及在 Java 中的应用
正则表达式是一种用于匹配字符串的模式,在许多编程语言中广泛使用。Java 正则表达式提供了强大的文本处理能力,能够对字符串进行查找、替换、分割等操作。 一、正则表达式的基本语法 正则表达式由普通字符和特殊字符组成。普通字符包括字母、数字和标点…...

深度学习(三)
5.Functional API 搭建神经网络模型 5.1利用Functional API编写宽深神经网络模型进行手写数字识别 import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom…...

文件系统小册(FusePosixK8s csi)【2 Posix标准】
文件系统小册(Fuse&Posix&K8s csi)【2 Posix】 往期文章:文件系统小册(Fuse&Posix&K8s csi)【1 Fuse】 POSIX:可移植操作系统接口(标准) 1 概念 POSIX:…...
vue 弹出框组件重复打开时,资源重新加载
新增或者编辑内容使用同一个弹出框,如何使数据可以重新加载? 1、绑定时间戳,有副作用,屏幕会闪烁一下 <el-dialog :key"timer" > </el-dialog> 2、v-if和:visible.sync同时使用 <el-dialogv-if"…...

图像的IO操作
代码: import cv2 as cvimport matplotlib.pyplot as plt#读取图像img cv.imread("../data/images/zidane.jpg")#显示图像#2.1 OpenCVcv.imshow("dili",img)cv.waitKey(0)cv.destroyAllWindows()#2.2 matplotlibplt.imshow(img[:,:,::-…...
关于 Vue.js 中`transition`组件使用:页面切换动画和标签移动动画都是要用到的
一、引言 在 Vue.js 中,transition组件提供了一种简单而强大的方式来实现页面过渡效果。它可以让元素在状态改变时,如进入或离开视图时,以平滑的动画方式进行过渡。通过transition,我们可以为应用增添更加生动和吸引人的用户体验…...
Flink Rest Basic Auth - 安全认证
背景 公司目前需要将Flink实时作业云化,构建多租户实时计算平台。目前考虑为了资源高效利用,并不打算为每个租户部署一套独立的Kubernetes集群。也就意味着多个租户的作业可能会运行在同一套kubernets集群中。此时实时作业的任务就变的很危险,因为网络可能是通的,就会存在…...

安全U盘和普通U盘有什么区别?
安全U盘(也称为加密U盘或安全闪存驱动器)与普通U盘肯定是有一些区别的,从字面意思上来看,就能看出,安全U盘是能够保护文件数据安全性的,普通U盘没这一些功能的,可随意拷贝文件,不防盗…...
大数据与数据科学的学科边界
大数据和数据科学是两个紧密相关但又不完全相同的学科。它们都关注数据的收集、管理、分析和解释,但侧重点有所不同。 大数据主要关注处理和分析大规模数据集的技术和方法。它涉及到数据存储、数据处理、数据挖掘、数据可视化和分布式计算等方面的技术。大数据的目…...

Chrome 源码阅读:跟踪一个鼠标事件的流程
我们通过在关键节点打断点的方式,去分析一个鼠标事件的流程。 我们知道chromium是多进程模型,那么,我们可以推测:一个鼠标消息先从主进程产生,再通过跨进程通信发送给渲染进程,渲染进程再发送给WebFrame&a…...

[C/C++]_[初级]_[在Windows和macOS平台上导出动态库的一些思考]
场景 最近看了《COM本质论》里关于如何设计基于抽象基类作为二进制接口,把编译器和链接器的实现隐藏在这个二进制接口中,从而使用该DLL时不需要重新编译。在编译出C接口时,发现接口名直接是函数名,比如BindNativePort,怎么不是_BindNativePort?说明 VC++导出的函数默认是使…...

MySQL排序操作
025排序操作 select .. from .. order by 字段 asc/descselect empno, ename, sal from emp order by sal asc;asc 不写的话,默认升序 多个字段排序 查询员工的编号、姓名、薪资,按照薪资升序排列,如果薪资相同的,再按照姓名升…...

问题:西周后期形成了能够传布四方、留存后世的兵书——著述年代最早的兵书——( )和( ). #媒体#知识分享
问题:西周后期形成了能够传布四方、留存后世的兵书——著述年代最早的兵书——( )和( ). A、《军志》 B、《军事》 C、《军政》 D、《孙子兵法》 参考答案如图所示...

kafka-消费者-指定offset消费(SpringBoot整合Kafka)
文章目录 1、指定offset消费1.1、创建消费者监听器‘1.2、application.yml配置1.3、使用 Java代码 创建 主题 my_topic1 并建立3个分区并给每个分区建立3个副本1.4、创建生产者发送消息1.4.1、分区0中的数据 1.5、创建SpringBoot启动类1.6、屏蔽 kafka debug 日志 logback.xml1…...

JavaWeb2-Vue
Vue 前端框架,免除原生JS中的DOM操作简化书写 (以前学过又忘了,现在才知道原来vue是前端的) 基于MVVM思想(model-view -viewModel)实现数据双向绑定 model是数据模型 view负责数据展示 即DOM 中间这个负责…...

《广告数据定量分析》读书笔记之统计原理2
3.相关分析:描述的是两个数值变量间关系的强度。(两个数值型变量之间的关系) (1)图表表示:散点图 (2)衡量关系强度指标:相关系数r。 (r的取值为-1到 1&…...

计算机视觉与模式识别实验2-2 SIFT特征提取与匹配
文章目录 🧡🧡实验流程🧡🧡SIFT算法原理总结:实现SIFT特征检测和匹配通过RANSAC 实现图片拼接更换其他图片再次测试效果(依次进行SIFT特征提取、RANSAC 拼接) 🧡🧡全部代…...
kerberos: Clock skew too great (37) - PROCESS_TGS
kerberos认证失败错误信息: Caused by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Clock skew too great (37) - PROCESS_TGS)at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:772)at sun.security.j…...
【MATLAB高级编程】入门篇 | 向量化编程
【入门篇】向量化编程 1. 什么是向量?2. 向量的创建2.1 行向量2.2 列向量2.3 使用冒号运算符2.4 使用`linspace`和`logspace`3. 向量的基本操作3.1 向量元素访问3.2 向量的长度3.3 向量的加法和减法3.4 向量的点乘和叉乘3.5 向量的元素乘法和除法4. 向量的高级操作4.1 逻辑索引…...
Debezium日常分享系列之:Debezium 2.7.0.Beta1发布
Debezium日常分享系列之:Debezium 2.7.0.Beta1发布 一、重大变化1.快照工件2.Oracle 二、新功能和改进1.在 z/OS 上支持 Db22.NATS JetStream 接收器身份验证改进3.JDBC 接收器 MariaDB 方言支持4.JMX 导出器添加到 Debezium 服务器5.使用 Debezium Operator 启用 J…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...