replace、replaceAll、replaceFirst
replace、replaceAll、replaceFirst这三个函数会java的同学估计都用过,笔者已经用了2年多,可是,我们真的懂他们吗?
概述一下他们三个的用法:
· replace(CharSequence target, CharSequence replacement),用replacement替换所有的target,两个参数都是字符串。
· replaceAll(String regex, String replacement),用replacement替换所有的regex匹配项,regex很明显是个正则表达式,replacement是字符串。
· replaceFirst(String regex, String replacement),基本和replaceAll相同,区别是只替换第一个匹配项。
接下来有个简单的需求,就是把源字符串中的a替换成\a,代码如下:
1 System.out.println("abac".replace("a", "\\a")); //\ab\ac
2 System.out.println("abac".replaceAll("a", "\\a")); //abac
3 System.out.println("abac".replaceFirst("a", "\\a")); //abac
结果让人大吃一惊,用了这么多年的替换,竟然有点蒙了。
源字符串是"abac",然后我们找到"a",把它替换成\a,由于\是java转义字符,所以想表达\a必须写成"\\a",第一个反斜线将第二个反斜线转义成普通字符串。
三个替换表达式,只有第一个replace函数的结果是正确的,问题出在哪呢?
replaceAll和replaceFirst要求第一个参数是正则表达式,"a"既能理解成字符串a,也可以理解成正则表达式a,所以第一个参数没问题。
问题就出在第二个参数上,如果读者仔细阅读replaceAll函数的注释,会发现有如下说明:
Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string; see Matcher.replaceAll. Use java.util.regex.Matcher.quoteReplacement to suppress the special meaning of these characters, if desired.
由于replaceAll和replaceFirst的第一个参数是正则,所以我们可以在第二个参数中做些小花样,比如有这样一个需求:把源字符串中的a替换成a后边紧邻的字符,代码如下:
1 System.out.println("abac".replaceAll("a(\\w)", "$1$1")); //bbcc
2 System.out.println("abac".replaceFirst("a(\\w)", "$1$1")); //bbac
正则的含义假设读者可以读懂,可以看出,在第二个参数中,可以用$符号获取分组的内容,本例中用$1取到了第一个分组的内容,即a后边紧邻的字符。
因此,$符号在第二个参数中是有特殊含义的,乱写会报错:
1 System.out.println("abac".replaceAll("a(\\w)", "$")); //Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
那假如我就想替换成$呢?这就需要转义字符:
1 System.out.println("abac".replaceAll("a", "\\$")); //$b$c
到这,读者可能会恍然大悟,原来反斜线在第二个参数中也有特殊含义(转义),所以如果我们想表达反斜线,就必须再转义一次:
1 System.out.println("abac".replaceAll("a", "\\\\a")); //\ab\ac
2 System.out.println("abac".replaceFirst("a", "\\\\a")); //\abac
简单理解一下,"\\\\a"中前边的反斜线分别转义后边的反斜线,让后边的反斜线就是普通字符串,这样在java内存中看到的字符串就是"\\a",然后replaceAll函数在处理时,再用前边的反斜线转义后边的反斜线,来表达后边的反斜线就是普通字符串,不是用来转义$的,最终内存中的字符串就是"\a",这样才可以成功将a替换成\a。
转义的问题确实纠结,通过本文,笔者希望读者以后使用这些函数时,能够保持清醒,能够意识到参数中的特殊字符,避免写出定时炸弹。
replace、replaceAll、replaceFirst的更多相关文章
- replace、replaceAll、replaceFirst的区别详解
String s = "my.test.txt"; System.out.println(s.replace(".", "#")); Sys ...
- java字符串的替换replace、replaceAll、replaceFirst的区别详解
如果不是刚刚复习了下正则表达式,我可能也不会注意到,原来String的replaceAll跟replaceFirst用到了正则表达式! 不多解释,看代码: String s = "my.te ...
- JAVA字符串的替换replace、replaceAll、replaceFirst的区别解析。
String str = "i.like.cat"; System.out.println(str.replace(".", "!")); ...
- java字符串的替换replace、replaceAll、replaceFirst的区别
看代码: String s = "my.test.txt"; System.out.println(s.replace(".", "#")) ...
- append、replace、replaceAll、indexof、lastIndexOf、substring的用法
1.append StringBuffer buf = new StringBuffer("Hard "): String aString = "Waxworks& ...
- java--字符串替换replace,replaceAll,replaceFirst
1.字符串替换,replace string s="abcdfersabcdsgacabc"; 将字符串中的abc替换成bdf s.replace("abc", ...
- Java字符串替换函数replace、replaceFirst、replaceAll
一.replace(String old,String new) 功能:将字符串中的所有old子字符串替换成new字符串 示例 String s="Hollow world!"; ...
- Excel函数——DATE、SUBSTITUTE、REPLACE、ISERROR、IFERROR
1.DATE DATE 函数返回表示特定日期的连续序列号.例如,公式 =DATE(2008,7,8) 返回 2008-7-8或39637,取决于单元格格式,但空单元格计算和默认为日期格式. DATE也 ...
- 05_整理String类的Length()、charAt()、 getChars()、replace()、 toUpperCase()、 toLowerCase()、trim()、toCharArray()使用说明
Question: 整理String类的Length().charAt(). getChars().replace(). toUpperCase(). toLowerCase().trim().toC ...
随机推荐
- JAVA 并发编程-读写锁之模拟缓存系统(十一)
在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保 ...
- 【bzoj3208】花神的秒题计划Ⅰ
记忆化搜索 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib ...
- 杂项-Java:Struct
ylbtech-杂项-Java:Struct Struts是Apache软件基金会(ASF)赞助的一个开源项目.它最初是Jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目.它通过 ...
- 正则表达式:(?=a)是什么意思?
1.(?=a) 表示我们需要匹配某样东西的前面. 2.(?!a) 表示我们需要不匹配某样东西. 3.(?:a) 表示我们需要匹配某样东西本身. 4.(?<=a) 表示我们需要匹配某样东西的后面. ...
- 采用jq链(end方法和andSelf()方法)
end()方法: <style type="text/css"> .m1{background:#09C;} .m2{border:1px solid #000;} & ...
- 搞笑代码注释,佛祖保佑 永无BUG
佛祖保佑 永无BUG 上传图片即可生成字符画,效果还不错, https://www.fontke.com/tool/image2ascii/ 神注释大全 https://github.com/Blan ...
- sql清空表数据后重新添加数据存储过程
ALTER PROCEDURE [dbo].[sp_add_Jurisdiction] @CTableName varchar(20), --当前要删除.新增的表 @filedkeyValue var ...
- P3174 [HAOI2009]毛毛虫(树形dp)
P3174 [HAOI2009]毛毛虫 题目描述 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大.例如下图左边的树(图 1 )抽出一部分就变成了右边 ...
- java自学-方法
上节介绍了流程控制语句,一个复杂的业务逻辑会由很多java代码组成,包含许多功能.比如说购物业务,就包含选商品.下单.支付等功能,如果这些功能的代码写到一起,就会显得很臃肿,可读性非常不好.java提 ...
- Androidstudio的安装与使用调试
1安装与基本使用 1.1androidstudio的安装 1.到android-studio\bin文件夹里面,根据自己的电脑配置,打开studio.exe或者studio64.exe 2.按照向导默 ...