百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

String 方法中 replace 和 replaceAll 详解

liebian365 2025-03-19 14:03 2 浏览 0 评论

前言

我们先做一个简单的概述:

  1. replace() 和 replaceAll() 都是常用的替换字符串的方法;
  2. 两者都是全部替换,可以把源字符串中的某一字符或字符串全部换成指定的字符或字符串;
  3. 如果只想替换第一次出现的,可以使用 replaceFirst();
  4. 这个方法也是基于规则表达式的替换,但与replaceAll()不同的是,只替换第一次出现的字符串;
  5. replaceAll() 和 replaceFirst() 所用的替换参数可以是普通字符串,也可以是正则表达式;
  6. 如果 replaceAll() 和 replaceFirst() 所用的参数据不是基于规则表达式的,那么它们与 replace() 替换字符串的效果、效率是一样的。

注意:执行了替换操作后,返回一个新的对象,源字符串的内容是没有发生改变的。

源码分析

来看看源码中关于两个方法的定义,我分别摘取了一段:

* String.class */
...
/** 
 * Replaces each substring of this string that matches the literal target sequence 
 * with the specified literal replacement sequence ...
 * 翻译:用指定的文字替换序列替换与文字目标序列匹配的字符串的每个子字符串。
 */
public String replace(CharSequence target, CharSequence replacement) {
	return Pattern.compile(target.toString(),Pattern.LITERAL).
		matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
    }
...

/** 
 * Replaces each substring of this string that matches the given regular expression 
 * with the given replacement...
 * 翻译:将与给定正则表达式匹配的字符串的每个子字符串替换为给定的替换。
 */
public String replaceAll(String regex, String replacement) {
	return Pattern.compile(regex).
		matcher(this).replaceAll(replacement);
}
...

通过方法的定义,我们发现:replaceAll() 在定义它的时候,就被赋予可以匹配正则表达式的功能。 通过源码,可以总结两点:

  1. String.replace() 和 String.replaceAll() 调用的方法是一样的,都是Matcher.replaceAll() 方法;
  2. replaceAll() 方法没有传入参数 “Pattern.LITERAL”;

就是这一点点的不同,决定了 replaceAll() 方法需要优先判断被替换的参数 regex 是不是一个正则表达式。

  • 如果是正则,执行正则替换;
  • 如果是字符串,执行字符串替换,此时和 replace() 就是一样的了。

replaceAll() 源码分析

我知道学技术的小伙伴都属于“刨根问底”栏目组的,下面我带大家看一看,参数 "Pattern.LITERAL"是怎么影响业务逻辑的:

1. String.replaceAll(String regex, String replacement) 函数如下:

它共调用了三个函数,作用分别是:

  • Pattern.compile(String regex) – 编译(解析)正则表达式,获得Pattern对象;
  • Pattern.matcher(CharSequence input) – 获取匹配器;
  • Matcher.replaceAll(String replacement) – 替换字符串;

顾名思义,我们需要解释的重点,就在 Pattern.compile(String regex) 方法中。

2. Pattern.compile(String regex) 函数如下:

它返回的是一个Pattern对象。

3. Pattern的构造函数如下:

这个构造函数是 private 级别的,不能被其他类直接调用,只能通过 Pattern 类的 compile(String regex) 和 compile(String regex, int flags) 调用。 该构造函数调用了 compile(),对 regex 参数的处理就发生在这个函数里面!!

4. Pattern.compile()函数如下:

其中:

  • ①中的参数"LITERAL"就是我们上面提到的那一点点不用(不清楚的可以再回看一下);
  • ①处的 if – else 语句,决定②处是否执行;
  • ②处的 matchRoot = expr(lastAccept);就是获得正则表达式匹配根结点的方法,若执行此方法,则开始进行正则表达式的匹配。

好了,再往下的代码我就不再演示了,有兴趣的小伙伴可以自己看一看。

代码论证

说了很多理论的东西,写几行代码验证下:

@Test
public void replaceTest() {
    String str1 = "Aoc.Iop.Aoc.Iop.Aoc";	    //定义三个一样的字符串
    String str2 = "Aoc.Iop.Aoc.Iop.Aoc";
    String str3 = "Aoc.Iop.Aoc.Iop.Aoc";

    String str11 = str1.replace(".", "#");	    // str11 = "Aoc#Iop#Aoc#Iop#Aoc"
    String str22 = str2.replaceAll(".", "#");	    // str22 = "###################"
    String str33 = str3.replaceFirst(".", "#");	    // str33 = "#oc.Iop.Aoc.Iop.Aoc"
}

由于“.”属于正则表达式的符号,所以 replaceAll() 方法执行的是正则替换。

转义符号 – “\”,需要格外注意下:

  • “\” 在 java 中是一个转义字符,所以需要用两个代表一个。 例如 System.out.println(“\\”);只打印出一个 “\”;
  • “\”也是正则表达式中的转义字符(replaceAll()的参数就是正则表达式),也需要用两个代表一个。 所以:“\\\\”会被j ava 转换成 “\\”,“\\” 又会被正则表达式转换成“\”。

看一个例子:

@Test
public void replaceTest() {
    String str1 = "blog.csdn.net/weixin_44259720/";
    String str2 = "blog.csdn.net/weixin_44259720/";
	    	
    String str11 = str1.replace("/", "\\");		// 转义
    String str22 = str2.replaceAll("/", "\\\\");	// 转义 + 正则匹配
}
	
输出结果相同:
    str11 = "blog.csdn.net\weixin_44259720\"
    str22 = "blog.csdn.net\weixin_44259720\"

小结

  1. replace 的参数是 char 和 CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence 即字符串序列的意思,说白了也就是字符串);
  2. replaceAll 的参数是 regex,即基于正则表达式的替换。比如,可以通过 replaceAll ("\d", “*”) 把一个字符串所有的数字字符都换成星号;
  3. String 类执行了替换操作后,返回一个新的对象,源字符串的内容是没有发生改变的。

作者:IT无知君
链接:
https://juejin.cn/post/7020951662546124837

相关推荐

python如何对字符串进行操作(python如何对字符串进行操作输出)

1.字符串的创建可通过直接赋值、构造或转义字符来创建字符串。#普通字符串s="Hello,World!"#多行字符串(使用三引号)multi_line_str='''Thisi...

Excel表格中11个常用的字符串函数

今天和大家聊聊常用的字符串函数,在不同的条件下,如何选择字符串函数很关键。下面我为大家列举了11个关于字符串的函数公式。一、EXACT(两个字符串进行结果比较)比较两个字符串是否完全相同(这里是要区分...

详细介绍一下Python中如何对字符串进行操作?

在Python中,字符串做为一种常见的数据处理类型,几乎在每个应用程序中都会被用到。而作为Python中使用最广泛的数据类型Python也是提供了很多强大的方法来支持对于字符串的处理操作。下面我们就来...

Java中你知道几种从字符串中找指定的字符的数量

遇到这样的问题,常规的思路估计就是遍历String,然后逐个对比。下面先看循环遍历循环遍历privatestaticintgetNum(StringoriginStr,Stringtarg...

C语言strcspn函数详解:字符串的“扫雷探测器”

strcspn是C语言标准库中的一个函数,定义在头文件中。它用于计算从字符串的开始到首次出现任何属于指定字符集合的字符之间的字符数量。换句话说,strcspn计算的是主字符串中不包含指定字符集...

如何使用 Python 的 f-string 进行字符串格式化

Python中的字符串格式化曾经有点麻烦。必须在...

java判断字符串中是否包含某个字符

1使用String类的contains()方法contains()方法用于判断字符串中是否包含指定的字符或字符串。语法如下:publicbooleancontains(CharSequence...

Python基础:f-string不同数据类型的格式化选项,终极指南!

上一篇文章我们介绍了4种字符串格式化方法,其中最现代、最直观的方式是f-string,从Python3.6开始引入,而且时不时就增加一些超级优雅的小改进。今天,钢铁老豆想要继续给大家展开介绍不同数据...

Excel查找指定字符串,返回相应的结果

通过下面的函数,可以实现查找指定字符串,若找到返回“有”,若找不到返回“无”。=IF(ISNUMBER(SEARCH("失业",G3)),"有","无")...

一个list中,有b.a.b.c.b.b.写个方法去掉所有b

importjava.util.ArrayList;importjava.util.List;publicclassRemoveBFromStringList{/**...

掌握Python f-string(掌握催眠能力之后的日常生活)

f-string,通常称为格式化字符串文本,是Python3.6中添加的一项强大功能,它提供了一种将表达式包含在字符串文本中的清晰实用的方法。,...

深入了解字符串:定义、转义字符和字符串下标

字符串是编程中常见的数据类型之一,用于表示文本信息。在绝大多数编程语言中,字符串都是由一系列字符组成的序列,可以包含字母、数字、符号以及空格等。字符串的定义:...

100个Java工具类之70:字符串处理工具类StringUtils

StringUtils是常用的工具类,提供大量处理字符串的静态方法。StringUtils主要特点...

Shell中针对字符串的切片,截取,替换,删除,大小写操作

切片返回字符串变量var的长度...

Sqlite - 常规函数 - RTRIM(sqlite命令行工具)

在SQLite中,RTRIM函数是一个用于处理字符串的函数,其主要作用是移除字符串右侧(尾部)的指定字符。如果不指定要移除的字符,默认会移除字符串右侧的空格字符。以下是对RTRIM函数的详细...

取消回复欢迎 发表评论: