replace() 和 replaceAll() 都是常用的替换字符串的方法:
两者都是全部替换,即把源字符串中的某一字符或字符串全部换成指定的字符或字符串。
如果只想替换第一次出现的,可以使用 replaceFirst()。这个方法也是基于规则表达式的替换,但与replaceAll()不同的是,只替换第一次出现的字符串;
另外,如果 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() 在定义它的时候,就被赋予可以匹配正则表达式的功能。
通过源码,也可以看到两点:
这一点点的不同,就决定了 replaceAll() 方法需要优先判断被替换的参数 regex 是不是一个正则表达式。如果是正则,执行正则替换;如果是字符串,执行字符串替换,此时和 replace() 就是一样的了。
我知道学技术的小伙伴都属于“刨根问底”栏目组的,下面我带大家看一看,参数 "Pattern.LITERAL"是怎么影响业务逻辑的:
顾名思义,我们需要解释的重点,就在 Pattern.compile(String regex) 方法中。
Pattern的构造函数如下:
这个构造函数是 private 级别的,不能被其他类直接调用,只能通过 Pattern 类的 compile(String regex) 和 compile(String regex, int flags) 调用。
该构造函数调用了 compile(),对 regex 参数的处理就发生在这个函数里面!!
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() 方法执行的是正则替换。
转义符号 – “\”,需要格外注意下:
看一个例子:
@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\"
更多精彩,请关注我的"今日头条号":Java云笔记
随时随地,让你拥有最新,最便捷的掌上云服务