“1。”
在日常工作中,会经常用到replace方法,最常见的如:
str.replace("http", "https");
上面的写法确实很实现我们的需求(将字符串“http”替换为“https”),但是我们真的了解replace的用法吗?
01
—
方法定义
String 类提供了字符(串)替换的方法,有4个方法,如下图:
从定义看,方法1是替换单个字符,方法2是替换字符序列(字符串),方法3是替换出现的所有字符串,方法4是替换第一个出现的字符串。
方法2和方法3参数可以认为一样,但是为什么要定义两个方法呢?
02
—
测试
我们用下面的代码测试这4个方法:
结果如下
从结果可以看出,前3个方法均是搜索字符串,替换所有出现的目标字符,第4个方法是替换第一次出现的字符串,这是比较符合我们的预期。
然而这个例子并不能看出来方法2 和方法3 的区别,那么我们只有看源码才能知其所以然了。
03
—
阅读源码
以下是replace方法的源码:
以下是replaceAll方法的源码:
可以看到,这两个方法均是通过正则来替换字符串的,不同的地方有两处:
第一个参数:replace方法是通过Pattern.compile(target.toString(), Pattern.LITERAL)来编译正则表达式的,Pattern.LITERAL表示匹配的是字面值(即忽略正则表达式语法),replaceAll方法的第一个参数就是正则表达式,
第二个参数:replace方法会调用Matcher.quoteReplacement(replacement.toString()),得到替换字符串的字面值,那么它们有什么区别呢?
首先我们分析第一个参数的不同之处,看下面的代码:
经过上面的分析,我们可以想到,
String replaceCharSeq = str.replace("\\d","@");
上面这行代码不会将"\d"(数字字符匹配)来匹配数字,而是匹配 "\d";所以可以想象该语句会将"\\d"替换为"@"
String replaceAll = str.replaceAll("\\d","@");
而这行代码会将"\d"作为元字符匹配数字,所以会将字符串中的"123"替换为"@@@"。
结果如下,完全符合我们的预期:
再分析第二个参数的不同之处,假如有这样的需求:将上述字符串中的''a"替换为"\a",那么要怎么写呢?下面这种写法会达到目的吗?
测试结果如下,可以看到replace方法能实现上述需求,replaceAll方法并没有实现替换工作:
其实我们去看Pattern.compile(regex).matcher(this).replaceAll(replacement)的源码,就能知道,replaceAll方法会对"\\a"的"\\"作为转义字符来处理,所以这里的str.replaceAll("a", "\\a")等同于str.replaceAll("a", "a")。
注意1:replaceAll还可以捕获匹配的字符串,如下面的代码($1表示正则表达式捕获到的字符串):
注意2:replaceAll 替换字符串中出现$时要加转义符,请看下面的注释(Matcher.replaceAll(String replacement)):
综上,replace和replaceAll的区别主要是
replace使用正则去匹配目标字符串的字面值;
replace只取替换字符串的字面值;
而replaceAll的目标字符串和替换字符串都为正则表达式。
领取专属 10元无门槛券
私享最新 技术干货