【Java】正则表达式在字符串方法中的使用

一、概述

在之前我们已经学习过一个方法:matches(),这个方法可以用来判断字符串是否满足正则表达式的规则。

public String[] matches(String regex)  // 判断字符串是否满足正则表达式的规则

String 类中,还有两个方法是识别正则表达式的。

第一个方法:replaceAll(),这个方法看它的方法名我们也能猜出来它的作用

public String replaceAll(String regex, String newStr)  // 按照正则表达式的规则进行替换,并且只要字符串满足正则表达式的规则,所有的地方都会进行替换

第二个方法:split()

public String[] split(String regex)  // 按照正则表达式的规则切割字符串

二、replaceAll 方法

1)编写代码

有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
要求1:把字符串中三个姓名之间的字母替换为vs,替换完成之后就变成了:小诗诗vs小丹丹vs小惠惠

第一步,肯定是将需求先定义成一个字符串

String s = "小诗诗dqwefqwfqwfwq12312小丹丹fsdafqwfqwfwq1232412小惠惠";

然后就可以使用 s 去调用 replaceAll() 方法,方法有两个参数,ctrl + p 获取形参列表。

形参1:regex,即 正则表达式

参数2:replacement,是 String 类型的,因此我们将 vs 以字符串的形式放在第二个参数就行了。

image-20240423102745099

现在我们就可以来写替换方法了,中间这段,有字母有数字,但是没有下划线 :[\\w&&[^_]] 表示我要在前面的范围中去掉下划线。

这样的字符出现几次呢?不知道,但至少出现一次,因此这里写 + 就行了。

下面式子就表示:我要在字符串中,把所有满足正则表达式的地方都替换成 vs

由于字符串本身是不能改变的,因此必须将替换后的结果返回才行。字符串 s 本身是不发生改变的。

String result1 = s.replaceAll("[\\w&&[^_]]+", "vs");

那这个方法在底层是怎么实现的呢?


2)查看源码

选中 ctrl + b 跟进 replaceAll(),看见源码后,可以发现这个代码非常的眼熟!它就是我们刚刚在爬取数据的时候写的代码。

首先用 Pattern 调用里面的静态方法 compile(),将正则表达式 regex 传递进去,此时我们就能得到正则表达式的对象。

然后用正则表达式的对象去调用 matcher() 方法,Pattern.compile(regex).matcher(this) 这个整体就可以得到文本解析器的对象

image-20240423103654309

this 表示的是方法调用者的地址值,当前 replaceAll()s 这个字符串调用的,因此这里相当于就是将调用者,也就是 s 字符串放到这里。合起来就是:用 文本解析器的对象 去读取这个字符串。

image-20240423104021254

最后再使用 文本解析器的对象 去调用 replaceAll(),此时要注意了,这个 replaceAll() 和上面的 replaceAll() 不是一个方法,第一个 replaceAll() 是定义在 String 中的;而第二个 replaceAll() 是由文本解析器调用的,因此第二个 replaceAll() 应该是 Matcher类 里面的方法。

image-20240423104552499

选中第二个 replaceAll() ctrl + b 跟进,此时就跳转到了 文本解析器 这个类里面。

在这个方法里面,它就是不断的 find()

image-20240423104727375


3)总结

方法在底层跟之前一样也会创建文本解析器的对象。然后从头开始去读取字符串中的内容,只要有满足的,那么就用第二个参数去替换。


三、split 方法

1)编写代码

假设现在字符串是 小诗诗a小丹丹a小惠惠

当你执行完下面这行代码时,就相当于它会把 小诗诗a小丹丹a小惠惠 这个大字符串按照 a 进行切割。

s.split("a");

写完后,大的字符串应该就被分成了三小段。

方法的返回值是 String[],因此它会将切割后的字符串放到数组中返回。

image-20240423105548489

这个是比较简单的切割,那我现在要按照正则表达式的规则进行切割怎么办?

有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
要求2:把字符串中的三个姓名切割出来

其实也是一样的,将上面讲解 replaceAll() 时候的正则表达式复制粘贴过来

String[] arr = s.split("[\\w&&[^_]]+");

然后遍历 arr

for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

运行结果如下

image-20240423105902117

它在切割的时候,同样也是从头到尾去找符合正则表达式规则的字符串。

切割完成后就有三个小串,再将这三个小串放到数组中,然后返回数组。

image-20240423110053393


四、扩展

String类 中有很多很多的方法,那我怎么知道哪些方法是识别正则表达式的,哪些方法是不识别正则表达式的呢?

不着急,我们打开一下 API帮助文档,搜索 String

其实我们判断一个方法是否识别正则表达式是有技巧的,例如我们找到 matches() 方法。

你会发现,mathces() 方法的形参名字叫做 regex,这个单词就是正则表达式的意思。

image-20240423110529062

因此在Java中,一般会有这样的习惯:如果一个方法的形参叫 regex,那么这个方法就一定识别正则表达式。

此时我们可以用这里的规律来找 replace()split()

可以发现它们的形参都叫 regex

replaceFirst() 方法是替换第一个匹配到的,方法的形参也叫做 regex,因此这个方法它也是识别正则表达式的。

再来看看我们之前学习的替换的方法:replace(),可以发现两个 replace() 的形参都不叫 regex,因此这两个方法就不能识别正则表达式。如果你强行把正则表达式传递过去,那么它也只是当做普通的字符串而已

image-20240423110815161

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值