大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: Java语法 修改讲义

复习:正则表达式

正则

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)的正则表达式

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


作业

见:J&C:字符串:值类型?/ 池 / 常用方法 / StringBuilder / 正则

学习笔记
源栈学历
今天学习不努力,明天努力找工作

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 Java语法 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码