Java:字符串:正则:匹配 / 查找 / 替换

更多
2020年12月09日 14点06分 作者:叶飞 修改

复习:正则表达式

正则

java.util.regex包中提供了两个核心对象:

Pattern和Matcher

pattern对象只能通过其静态方法compile()获得:
Pattern pattern = Pattern.compile("\\d+");

传入的参数就是字符串格式的正则表达式。

注意pattern的编译是一个比较消耗性能的操作,尽可能的一次编译多次使用!

matcher对象又要通过pattern对象获得

Matcher matcher = pattern.matcher(target);
传入的参数就是要匹配的字符串,比如:
String target = "666";

匹配

目标字符串是否符合正则表达式的要求,这在进行校验的时候非常有用:
if (matcher.matches()) {
	System.out.println("matched……");

演示:将targe换成:

String target = "hello, 源栈,加油2022!O(∩_∩)O哈哈~,666";

查找和替换

查找使用find()方法,而且它是一个“连续”的过程,可以一直调用:
while (matcher.find()) {
	System.out.println("matcher.start():"+ matcher.start());
	System.out.println("matcher.start():"+ matcher.end());	
}

start()和end()可以获取查找到的字符串所在的起始位置。

还可以直接进行替换:

System.out.println(matcher.replaceFirst("xxx"));
System.out.println(matcher.replaceAll("xxx"));	

group

但如果我要查看查找/匹配到的字符串怎么办?使用group()方法:

  • 不传参数,或者参数0,表示所有内容
    while (matcher.find()) {
    	System.out.println(matcher.group());			
    }
  • 传入整型参数n或者group的名字,表示第n个(从1开始)或者指定名称的分组中的内容(复习:正则表达式中group的写法)
    Pattern pattern = Pattern.compile("(\\d)\\1");
    System.out.println(matcher.group(1));
    Pattern pattern = Pattern.compile("(?<digit>\\d)\\k<digit>");
    System.out.println(matcher.group("digit"));	

有了group之后,replaceXXX()的参数就可以使用$开头(后接分组序号或名字)的字符串表示分组:

System.out.println(matcher.replaceFirst("$1"));
System.out.println(matcher.replaceAll("${digit}"));

appendReplacement()

很多时候,我们需要大量的、带条件(比如数字能被3整除)的替换:

while (matcher.find()) {
	if (Integer.valueOf(matcher.group())%3==0) {
		//怎么办???				
	}

这样是不行的:

result = matcher.replaceAll("(3n)");
注意:replaceFirst()和replaceAll()都会重置(reset)matcher……,形成死循环!

只能使用matcher.appendReplacement()方法:

  1. 准备一个StringBuffer对象
    StringBuffer sb = new StringBuffer();
  2. 在matcher.find()的while循环中
    matcher.appendReplacement(sb, replaced);
  3. 在while循环结束之后,还要附上while循环中没能处理的尾巴
    matcher.appendTail(sb);
F2/F3演示讲解其过程……

替换分组中的内容

注意:不是替换整个正则表达式匹配的内容,而是其中分组的内容!比如:
String target = "hello, 源栈,加油2022!(666,赞……)大飞哥英俊潇洒风流倜傥(吐了,5~)";
使用正则表达式:
Pattern pattern = Pattern.compile("(\\D*(\\d+).*?)");

能匹配到的是:

  • (666,赞……)
  • (吐了,5~)

但我们要替换的,是分组中的:666和/或5。

所以需要在上述while循环中额外的加入一步:

if (Integer.valueOf(matached) % 3 == 0) {                            
    matcher.appendReplacement(sb,  matcher
        .group()  //(666,赞……) 
        .replace(matached,"(3n)"));
} // else nothing

利用group()和group(1),将(666,赞……)替换成((3n),赞……)之后再进行appendReplacement()的操作。

字符串方法

Java还提供了由String对象直接调用的、可以使用正则表达式的方法:

System.out.println(target.matches(regex));
System.out.println(target.replaceFirst(regex, "xxx"));
Arrays.stream(target.split(regex)).forEach(System.out::println);
F3演示:他们实际上都是调用了Pattern和Matcher对象,且在方法体中编译(compile)的正则表达式

所以,@想一想@:该不该在循环中使用这些方法?

Java 字符串 正则
赞: 0 踩: 0

打赏
已收到打赏的 帮帮币

你的 打赏 非常重要!
为了保证文章的质量,每一篇文章的发布,都已经消耗了作者 1 枚 帮帮币
没有“帮帮币”,作者无法发布新的文章。

全系列阅读
评论 / 0

后台开发


其他:WebForm和WebApi

其他ASP.NET框架,如WebForm、WebApi……

RazorPages(Core)

微软推荐的、最新的、基于Razor页面和.NET core的新一代Web项目开发技术,包括Razor Tag Helper、Model绑定和Validation、Session/Cookie、内置依赖注入等……

MVC(Framework)

过去两年间最流行的、基于.NET Framework和MVC模式的ASP.NET MVC框架,主要用于讲解安全、性能、架构和各种实战功能演示……

C#语法

从入门的变量赋值、分支循环、到面向对象,以及更先进的语言特性,如:泛型、Lambda、Linq、异步方法等…………

Java语法

面向过程的变量赋值、分支循环和函数封装;面向对象的封装、继承和多态;以及更高阶的常用类库(集合/IO/多线程……)、lambda等

Java Web开发

分层架构和综合实战

J&C

Java和C#共有的语法

全部
关键字



帮助

反馈