首页 > 编程语言 >javase-15、正则表达式

javase-15、正则表达式

时间:2024-12-16 19:56:11浏览次数:5  
标签:字符 匹配 String 正则表达式 Pattern 字符串 15 javase

一、初识正则表达式

1、概念

正则表达式是对字符串操作的一种逻辑公式,它会将事先定义好的一些特定字符,以及这些特定字符的组合,组成一个规则字符串,并且通过这个规则字符串表达对给定字符串的过滤逻辑。

一条正则表达式也称为一个模式,使用每个模式可以匹配指定文本中与表达式模式相同的字符串。正则表达式由普通字符元字符预定义字符集组成,其中普通字符包括大小写字母和数字。

常见用途

  • 数据验证:比如电话号码、邮箱等

  • 替换文本:快速找到特定文本,用于替换

  • 快速提取字符串:基于匹配规则,快速从文档中查找或提取子字符串

3、正则的用途举例

案例1

以下哪些是四大名著?
A.西游记
B.三国演义
C.水浒传
D.红楼梦
你喜欢哪些课程?
A.python
B.java
C.hadoop
D.爬虫
执行3/2后的结果正确的是
A、1
B、1.0
B、1.5
B、0

以上排版比较浪费空间,将其变为一行


请将选项后面的.换成


案例2

Zhangsan like orange or apple

将or替换为and


二、基本语法

1、普通字符

正则表达式中的普通字符,由没有显示的指定为元字符的打印和非打印的字符组成,普通字符没有其它含义,表示它本身

举例

hello world

匹配hello

hello

2、元字符

使用简单的元字符表达某一类字符,下面列出常用的匹配方式:

预定义字符类

元字符描述
.**默认模式:**匹配任何1个字符但换行除外;**DOTALL模式:**匹配任意字符
\d一个数字:[0-9]
\D非数字:[^0-9]
\h水平空白字符:[ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]
\H非水平空白字符:[^\h]
\s空白字符:[ \t\n\x0B\f\r]
\S非空白字符:[^\s]
\v垂直空白字符:[\n\x0B\f\r\x85\u2028\u2029]
\V非垂直空白字符:[^\v]
\w单词字符:[a-z,A-Z,_,0-9]
\W非单词字符:[^\w]

POSIX 字符类(仅限 US-ASCII)

元字符描述
\p{Lower}小写字母字符:[a-z]
\p{Upper}大写字母字符:[A-Z]
\p{ASCII}所有 ASCII:[\x00-\x7F]
\p{Alpha}字母字符:[\p{Lower}\p{Upper}]
\p{Digit}十进制数:[0-9]
\p{Alnum}字母数字字符:[\p{Alpha}\p{Digit}]
\p{Punct}标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_{
\p{Graph}可见字符:[\p{Alnum}\p{Punct}]
\p{Print}可打印字符:[\p{Graph}\x20]
\p{Blank}空格或制表符:[ \t]
\p{Cntrl}控制字符:[\x00-\x1F\x7F]
\p{XDigit}十六进制数字:[0-9a-fA-F]
\p{Space}空白字符:[ \t\n\x0B\f\r]

举例

重庆大学    张三,ZhangSan 	8000元  重庆万州
重庆大学    李四,Lisiq		8800元  重庆万州 
重庆大学    王五,Wangwu 		9800元  四川成都

思考,匹配工资信息

\d\d\d\d

思考,匹配中文姓名

\s\s,
其中,用于辅助定位

思考,匹配英文姓名


3、 转义字符

我们已经学了部分元字符,比如. ? + *等,那如果我们想要查找元字符本身,比如要查找. 或者 * ,就出现了问题:没办法指定它们,因为它们会被解释成别的意思。这时就得使用 \来取消这些字符的特殊意义,从而表示字符字面量。

元字符转义字符
$\$
.\.
+\+
*\*
?\?
^\^
/\/
\\\
(\(
)\)
[\[
]\]
{\{
}\}

举例

<script src="student.js"></script>
<script src="score.xml"></script>

取出文件名

\w+\.\w+
说明:
	\w+:中的【+】表示,\w重复1次或多次。说人话,能匹配1个或多个字母
	\.:表示【.】的转义字符,因为【.】在正则表达式中,有特殊的含义

举例

apple's price is $10.01 per kg.
apple's price is $10.02 per kg.

取出价格

\d+\.\d+

4、字符集

在正则表达式语法中,方括号表示字符范围,也称字符集(或者叫字符组)。

字符类说明
[abc]a、b、c
[^abc]^ 表示取反,除 a、b、c 以外的其它字符
[a-zA-Z]- 表示连续,匹配所有字母字符
[0-9]- 表示连续,匹配所有数字字符
[a-c[x-z]]a到c,或 x 到 z,等价于 [a-cx-z],(并)
[a-z&&[def]]&&表示and,等价于 [def],(交)
[a-z&&[^bc]]a到z,但bc除外,等价于[ad-z],(差)

举例

124 156 111 1337
92 20 999 666

匹配所有的偶数数字

[02468]

匹配所有的偶数

\d*[02468]
说明:
\d*:【*】匹配\d 0次或多次,说人话:匹配0个或多个数字
[02468]:匹配1个偶数数数字

5、量词

上面我们学会的是单个字符的匹配,如果要表达多个类似的字符,只能通过复制多次的方式,比如我们要查找5个连在一起的数字,要写成\d\d\d\d\d,按程序员的思维,显然不合理,比如我们要表示1000个数字、任意多个数字、…

接下来介绍如何通过量词来表示上面的情形,下面列出了几种量词的写法:

量词含义举例
X?X出现 0次 或 1次\d? 0个或1个数字
X+X出现 1次 或 多次\d+1个或多个数字
X*X出现 0次 或 n次\d* 0个或多个数字
X{m}X出现 m次\d{3} 3个数字
X{m,}X出现 至少m次\d{2,} 至少3个数字
X{m,n}X出现 m~n次0\d{2,3} 0后面根2-3个数字

举例

ggle gogle google gooogle goooogle gooooogle goooooogle gooooooogle goooooooogle

匹配上面所有的字符串

go*gle
说明:
o*:o可以出现0次或多次

举例

重庆大学    张三,ZhangSan 	80000元  重庆万州
重庆大学    李四,Lisiq		8800元  重庆万州 
重庆大学    王五,Wangwu 	9800元  四川成都

思考,匹配工资信息

\d+

思考,匹配中文姓名

(\s+),
说明:【,】用于定位,()表示分组,方便后续通过分组编号取出这部分数据

思考,匹配英文姓名

,(\w+)
说明:【,】用于定位,()表示分组,方便后续通过分组编号取出这部分数据

举例

13612345678
13612345678abc
24654897132
12306123456

匹配手机号码

简易版本
1[3456789]\d{9}$
说明:【$】表示以\d{9},也就是9个数字结尾,具体用法见出面的边界。如果不写【$】13612345678abc也会被匹配

6、边界

如何表示一个字符串的起始位置和结束位置呢,这便是我们要讲的边界,这里先给几个简单的边界表示

边界匹配器描述
^一行的开头,^hi.*,以hi开头的行
$一行的结尾,.+\.jpg$,以.jpg结尾的行
\b单词,边界,指的是占位的字符左右的间隙位置,\bor\b,匹配两边是边界的or
\B非单词,边界

注意:

  • 单词指的是 \w 可以匹配的字符,即数字、大小写字母以及下划线 [0-9a-zA-Z_]
  • 边界 指的是占位的字符左右的间隙位置,边界是零宽断言,只匹配位置, 不匹配字符

举例

Zhangsan like orange or apple

将or替换为and
【老师你也太坏了,不我是让你爱上正则表达式】

查找框里写:\bor\b
替换框里写:and

7、选择、分组和、向后引用

1)选择(或分支)

正则表达式里的选择条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用 | 把不同的规则分隔开。

X|Y	任何一个X或者Y

比如要识别如下两种固话号码,

0991-8585671
023-58102054
(0991)8585671
(023)58102054

则可以写成

0\d{2,3}-?\d{7,8}|\(0\d{2,3}\)\d{7,8}

2)分组

概念

可以使用小括号( )来指定一个子表达式(也叫分组),例如:

(http)(www.*com)
(http)?(www.*com)  http作为一个整体,可有可无  

组号

捕获组通过从左到右计算它们的左括号来编号

例如,在表达式 ((A)(B(C))) 中,有四个这样的组:
1号分组:((A)(B(C)))
2号分组: (A)
3号分 :(B(C))
4号分组 :(C)
注意:分组编号是从1开始的,0号分组代表整个表达式

例子

还记得刚写的两种固话的匹配吗,可以写成

(\(0\d{2,3}\)|0\d{2,3}-?)\d{7,8}

3)分组捕获与后向引用

作用:将前面分组匹配到的结果(内容),以组号的方式引用,给到后续表达式继续使用。
说明:默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

例子

请找到出左右对称的信息

===welcome===
==hello==
==你好=
==吃了吗===

例子

匹配重复单词的字符串

go go 
kitty kitty
\b(\w+)\b\s+\1\b
说明:\1中的1表示组号,在这里表示(\w+)的匹配结果

8、贪婪、懒惰

先来看个例子:

123abc123456abc

如果想找出123abc123456abc两个字符串,你兴奋的写下了.*abc,结果发现只匹配了一次,把整个字符串匹配了。这便是我们要讲的匹配模式。

1)贪婪

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符,这被称为贪婪匹配

示例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索 aabab的话,它会匹配整个字符串aabab

属于贪婪模式的量词,也叫做匹配优先量词,包括:“{m,n}”、“{m,}”、“?”、“*”和“+”。

2)懒惰

如果想要匹配尽可能少的字符呢,这就是懒惰匹配模式。

只要在量词后面加上一个问号?就可以了。

比如前面的示例,你只需要将正则表达式写为如下形式即可:

.*?abc

懒惰匹配总是出现在有量词的地方,有如下懒惰量词:

语法描述
*?重复任意次,但尽可能少重复
+?重复1次或更多次,但尽可能少重复
??重复0次或1次,但尽可能少重复
{n,}?重复n次以上,但尽可能少重复
{m,n}?重复m到n次,但尽可能少重复

注意

问号(?):问号有两种场景

  • 一是以量词方式使用,表示?前面的子表达式或者字符出现1次或者0次;
  • 二是出现在量词后面,表示懒惰匹配。

三、在String类中使用正则

String类提供了3个实例方法支持正则操作

① matches 匹配

boolean matches(String regex)
    判断此字符串是否与给定的 正则表达式 匹配。

例如:

// 判断是不是一个正确的电话号码
String tel = "023-58580000";
boolean matches = tel.matches("\\d+-\\d+");
System.out.println(matches);

② split 拆分

String[] split(String regex)
    围绕给定 正则表达式 的匹配项拆分此字符串。
String[] split(String regex, int limit)
    围绕给定 正则表达式 的匹配项拆分此字符串。

例如:

// 按正则对字符串进行拆分
String stuInfo = "zhangsan china-cq 1985/11/12";
//String[] rst = stuInfo.split(" |-|/");
String[] rst = stuInfo.split("[ -/]");
for (String item : rst) {
    System.out.println(item);
}

③ replace相关

String  replace(String  old, String  new)
String  replaceFirst(String  regex, String  replacement)
     使用replacement替换regex的第一个匹配。
 String  replaceAll(String  regex, String  replacement)
     使用replacement替换regex的所有匹配。

例如:

(86)023-12345670
021:12345671
010-12345672
需要得到如下结果
(023)12345670
(021)12345671
(010)12345672
String stuInfo = """
    (86)023-12345670
    021:12345671
    010-12345672""";
	String string = stuInfo.replaceAll("(\\(86\\))?(\\d{3})(-|:)", "($2)");
System.out.println(string);

四、Pattern类和Matcher类

  • Matcher类不能单独使用,用于配合Pattern类。
  • Pattern类根据正则表达式创建匹配规则,Matcher根据匹配规则执行具体的匹配操作。

1、创建匹配模式(规则)

使用 Pattern.compile() 静态方法,编译正则表达式字符串,形成模式对象(匹配规则

static Pattern compile(String regex)
    将给定的正则表达式字符串,编译成一个模式。
static Pattern compile(String regex, int flags)
    将给定的正则表达式字符串,编译成具有【给定标志】的模式。
    【flags可以取以下值】
	Pattern.CANON_EQ 启用规范等价。
	Pattern.CASE_INSENSITIVE 启用不区分大小写的匹配。【重要】
	Pattern.COMMENTS 模式中允许空格和注解。
	Pattern.DOTALL 启用 dotall 模式。【重要】
	Pattern.LITERAL 启用模式的文字解析。
	Pattern.MULTILINE 启用多行模式。【重要】
	Pattern.UNICODE_CASE 启用 Unicode 感知大小写折叠。
	Pattern.UNICODE_CHARACTER_CLASS 启用Unicode版本预定义字符类和POSIX字符类.
	Pattern.UNIX_LINES 启用 Unix 行模式。

例如:

String phone = "13100000000";
// 获得模式对象(匹配规则)
Pattern pattern = Pattern.compile("1[345789]\\d{9}");  

2、创建匹配器

根据模式(匹配规则)生成匹配器。使用 Pattern对象的 matcher(CharSequence input) 方法,创建匹配器

Matcher类用于,在给定的Pattern实例的模式控制下进行字符串的匹配工作

例如:

String phone = "13100000000";
Pattern pattern = Pattern.compile("1[345789]\\d{9}");  // 匹配规则
Matcher matcher = pattern.matcher(phone); // 匹配器

3、匹配器的常用方法

匹配器,Matcher的实例对象

① matches匹配
"abc".matches("\w{3}")
boolean matches()
    字符串,是否与正则表达式【完全】匹配

例如:

String phone = "13100000000";
Pattern pattern = Pattern.compile("1[345789]\\d{9}");  // 编译后的模式 
Matcher matcher = pattern.matcher(phone);
System.out.println(matcher.matches());
② lookingAt匹配
boolean lookingAt()
    字符串的【开始位置】,是否有和正则表达式匹配的内容

例如:


③ find匹配
boolean find()
    字符串中,是否有【与位置无关】和正则表达式匹配的内容
boolean	find(int start)
    字符串中【从start指定的地方开始】,是否有【与位置无关】和正则表达式匹配的内容

例如:


④ groupCount 匹配
int groupCount()
    返回匹配到的分组(结果)个数

例如:


⑤ group

获得匹配结果,注意 要先调用匹配方法,后才能获得匹配结果,否则报错

String group();  String group(0);
    //返回匹配到的【整体】结果
String group(int group);
    //根据【分组编号,0表示完整结果,组号从1开始】,获取匹配到的结果

例如:


⑥ replaceAll
String replaceAll(String replacement)
    将正则表达式对应的【所有】【完整匹配】结果,使用字符串替换,并返回替换后的新字符串

例如:


⑦ replaceFirst
String replaceFirst(String replacement)
     将正则表达式对应的【第一个】【完整匹配】结果,使用字符串替换,并返回替换后的新字符串

例如:


⑧ 其他方法见API手册

4、其它相关用法

① 使用 pattern 匹配字符串

使用 Pattern.matches() 静态方法,判断正则表达式与字符串【完全】匹配。

Static boolean matches(String regex, CharSequence input)

例如:

// 判断手机号格式是否正确
String phone = "13100000000";
System.out.println(Pattern.matches("1[345789]\\d{9}", phone));

② 使用 pattern 拆分字符串

Pattern.compile("[ -/]").split("张三 中国/重庆/巴南 2011-11-11");

标签:字符,匹配,String,正则表达式,Pattern,字符串,15,javase
From: https://blog.csdn.net/weixin_42238065/article/details/144516098

相关文章

  • Spark向量化计算在美团生产环境的实践15
     1什么是向量化计算1.1并行数据处理:SIMD指令让我们从一个简单问题开始:假设要实现“数组a+b存入c”,设三个整型数组的长度都是100,那么只需将“c[i]=a[i]+b[i]”置于一个100次的循环内,代码如下:voidaddArrays(constint*a,constint*b,int*c,intnum){for(in......
  • 【2024-12-15】连岳摘抄
    23:59责任使我们看到自身的价值、生活的意义,并可摆脱人生的诸多烦恼。                                                 ——约翰卢伯克以我知天命的年龄,深知,平淡无......
  • springboot校园拼车跨平台-毕业设计源码21531
    基于uni-app的校园拼车跨平台移动应用的设计与实现摘 要随着移动互联网的普及和智能设备的广泛使用,移动应用已经成为人们日常生活中不可或缺的一部分。特别是在校园环境中,学生对于便捷、高效的移动应用需求日益增加。校园拼车作为一种绿色、环保且经济的出行方式,受到了越......
  • P1570 KC 喝咖啡
    不在赘述题目了。这是一道典型的分数规划题目。可以参考一下https://oi-wiki.org/misc/frac-programming/的内容。这里主要讲一下笔者自己在做题时遇到的一些困惑。为什么可以二分我们以$x[i]=1$表示取第$i$种材料,$x[i]=0$表示不取。那么最后的答案会有$ans=\sum\frac{v[i]......
  • CMU_15445_P3_Part1
    CMU_15445_P3_Part1这部分主要是实现一些基本的Plan_Node的Executor,我们可以首先通过一个列子来看,就是ProjectionPlan_Node的例子.Projection类型的PLAN_NODE是作为有条件的SELECT语句或者嵌套的SELECT语句的根节点,例如:SELECTa,bFROMt1WHEREc>10;......
  • 11.15
    分析器是一个可以生成另外一个程序的执行时间的统计结果的程序。分析器可以输出一份包含每个语句或函数的执行频度、每个函数的累积执行时间的报表。许多编译器套件,如 Windows 上的 VisualStudio 和 Linux 上的 GCC 都带有分析器,可以帮助我们找到程序中的热点。微软曾经......
  • 代码随想录算法训练营第四十五天|leetcode115.不同的子序列、leetcode583. 两个字符串
    1leetcode115.不同的子序列题目链接:115.不同的子序列-力扣(LeetCode)文章链接:代码随想录视频链接:动态规划之子序列,为了编辑距离做铺垫|LeetCode:115.不同的子序列哔哩哔哩bilibili思路:确实看不懂题目,还是看解析吧1.1视频后的方法有一种我看了视频,也没有那么理解是为......
  • Inobitec Dicom Viewer 2.15.x Crack
    InobitecDicomViewer2.15.x解决方案旨在满足现代医疗专业人士的需求,提供直观的工具,用于查看、分析和管理医学图像。我们的放射学软件无缝集成到临床工作流程中,有助于医学图像分割和手术规划。这一切都有助于改善患者治疗效果和诊断准确性,同时提高医疗保健效率。先进的功能......
  • H7-TOOL自制Flash读写保护算法系列,为凌欧LKS32MC45x/MC05x/MC08x制作使能和解除算法,支
    说明:很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。实际上当前已经发布的TOOL版本,已经自制很多了,比如已经支持的兆易创新大部分型号,新唐的大部分型号等。但是依然有些厂家还没自制,所以陆续开始为这些厂家提供读写保护支......
  • 上周热点回顾(12.9-12.15)
    热点随笔:· 重磅推出SdcbChats:一个全新的开源大语言模型前端 (.NET骚操作)· C#委托的前世今生 (付工上位机)· 关于服务器挖矿处理思路 (淡黄的cherry)· .NET静态代码编织——肉夹馍(Rougamo)5.0 (nigture)· 记一次.NET某差旅系统CPU爆高分析 (一线码农)· 一套......