java字符串的替換replace、replaceAll、replaceFirst的區(qū)別說明
字符串的替換replace、replaceAll、replaceFirst區(qū)別
如果不是剛剛復(fù)習(xí)了下正則表達(dá)式,我可能也不會(huì)注意到,原來String的replaceAll跟replaceFirst用到了正則表達(dá)式!
不多解釋,看代碼
String s = "my.test.txt"; System.out.println(s.replace(".", "#")); System.out.println(s.replaceAll(".", "#")); System.out.println(s.replaceFirst(".", "#"));
運(yùn)行結(jié)果:
my#test#txt
###########
#y.test.txt
是不是感覺很神奇?
其實(shí)懂正則表達(dá)式的應(yīng)該已經(jīng)發(fā)現(xiàn)了,是的,“.”是正則表達(dá)式的元字符,匹配除換行符以外的任意字符,所以replaceAll、replaceFirst才出現(xiàn)了這樣的結(jié)果。
而replace沒有用到正則表達(dá)式,但會(huì)把所有“.”替換掉,很多人可能會(huì)誤解replace是替換單個(gè),而replaceAll是替換全部,其實(shí)這是錯(cuò)的(我以前也是這么想的- -)。replace只是沒有用到正則表達(dá)式,但會(huì)替換所有匹配的字符串。
到這里一些不懂正則表達(dá)式的小伙伴可能就要喊坑爹了,“那我不想用正則表達(dá)式去替換第一個(gè)字符串腫么辦?”其實(shí)也很簡單,只要將元字符串轉(zhuǎn)義就行了。
s.replaceFirst("\\.", "#")
運(yùn)行結(jié)果:
my#test.txt
這里給個(gè)會(huì)被正則表達(dá)式識(shí)別的字符列表:
- .匹配除換行符以外的任意字符
- ^匹配字符串的開始
- $匹配字符串的結(jié)束
- *重復(fù)零次或更多次
- +重復(fù)一次或更多次
- ?重復(fù)零次或一次
當(dāng)然,正則可遠(yuǎn)不止這么點(diǎn),個(gè)人建議花點(diǎn)時(shí)間去學(xué)習(xí)一下比較好~
補(bǔ)充:String的split也是用到了正則表達(dá)式,使用的時(shí)候注意點(diǎn)哦!
replaceAll、replaceFirst使用需要注意的問題
昨天系統(tǒng)報(bào)錯(cuò),No group 6,上網(wǎng)查詢,說是replaceAll()的問題,就具體試驗(yàn)了一下,發(fā)現(xiàn)如果不注意,就會(huì)產(chǎn)生隱含的錯(cuò)誤。
java的String類的replaceAll方法是一個(gè)挺常用的方法,
類型定義如下
String replaceAll(String regex, String replacement)
有兩個(gè)參數(shù),第一個(gè)是被替換的字符串,是正則表達(dá)式,另外一個(gè)是替換成的字符串。
如果我們這樣寫
upLoadedFileName.replaceAll("","/"); ? ? ? ? ? // 把//替換為/
是沒有什么問題的,而且用好正則表達(dá)式可以實(shí)現(xiàn)很強(qiáng)的功能,如:
str.replaceAll("(?i)"+oldStr,newStr);//忽略大小寫;
但是,使用中我們一定要記住,不僅僅第一個(gè)參數(shù)是正則表達(dá)式,第二個(gè)也是,因此如果這兩個(gè)是可變參數(shù),就要注意參數(shù)的內(nèi)容,一篇文檔說應(yīng)該在所有的[ / ^ $ . | ? * + ( ) { }符號前面加上/符號。經(jīng)過我的測試(jdk1.4),只有/和$容易出錯(cuò)。
比如:
System.out.println("/".replaceFirst("/", "http://"));
系統(tǒng)會(huì)報(bào):
java.lang.StringIndexOutOfBoundsException: String index out of range: 1
System.out.println("/".replaceFirst("/", "x//"));
系統(tǒng)會(huì)報(bào):
java.lang.StringIndexOutOfBoundsException: String index out of range: 2
System.out.println("/".replaceFirst("/", "http://X"));
執(zhí)行結(jié)果是X
System.out.println("/".replaceFirst("/", "$6"));
執(zhí)行結(jié)果拋出例外:
java.lang.IndexOutOfBoundsException: No group 6
所以如果參數(shù)是變量,而且可能包含/或$,建議不要使用replaceAll和replaceFirst方法。
我實(shí)現(xiàn)了這兩個(gè)方法,大家可以直接引用
? ?/** ? ? * 字符串替換,從頭到尾查詢一次,替換后的字符串不檢查 ? ? * @param str ? ? 源字符串 ? ? * @param oldStr ?目標(biāo)字符串 ? ? * @param newStr ?替換字符串 ? ? * @return ? ? ? ?替換后的字符串 ? ? */ ? ?static public String replaceAll(String str, String oldStr, String newStr) ? ?{ ? ? ?int i = str.indexOf(oldStr); ? ? ?int n = 0; ? ? ?while(i != -1) ? ? ?{ ? ? ? ?str = str.substring(0, i) + newStr + str.substring(i + oldStr.length()); ? ? ? ?i = str.indexOf(oldStr, i + newStr.length()); ? ? ? ?n++; ? ? ?} ? ? ?return str; ? ?}?? ? ?/** ? ? * 字符串替換,左邊第一個(gè)。 ? ? * @param str ? ? 源字符串 ? ? * @param oldStr ?目標(biāo)字符串 ? ? * @param newStr ?替換字符串 ? ? * @return ? ? ? ?替換后的字符串 ? ? */ ? ?static public String replaceFirst(String str, String oldStr, String newStr) ? ?{ ? ? ?int i = str.indexOf(oldStr); ? ? ?if (i == -1) return str; ? ? ?str = str.substring(0, i) + newStr + str.substring(i + oldStr.length()); ? ? ?return str; ? ?} ? ?System.out.println(StringTools.replaceAll("/","/","http://"));
結(jié)果是/
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
仿釘釘流程輕松實(shí)現(xiàn)JSON轉(zhuǎn)BPMN完整實(shí)現(xiàn)過程示例
這篇文章主要為大家介紹了仿釘釘流程輕松實(shí)現(xiàn)JSON轉(zhuǎn)BPMN完整實(shí)現(xiàn)過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Java 詳細(xì)講解線程安全與同步附實(shí)例與注釋
線程安全是多線程編程時(shí)的計(jì)算機(jī)程序代碼中的一個(gè)概念。在擁有共享數(shù)據(jù)的多條線程并行執(zhí)行的程序中,線程安全的代碼會(huì)通過同步機(jī)制保證各個(gè)線程都可以正常且正確的執(zhí)行,不會(huì)出現(xiàn)數(shù)據(jù)污染等意外情況2022-04-04使用Spring boot + jQuery上傳文件(kotlin)功能實(shí)例詳解
本文通過實(shí)例代碼給大家介紹了使用Spring boot + jQuery上傳文件(kotlin) 功能,需要的朋友可以參考下2017-07-07Java實(shí)現(xiàn)整合文件上傳到FastDFS的方法詳細(xì)
FastDFS是一個(gè)開源的輕量級分布式文件系統(tǒng),對文件進(jìn)行管理,功能包括:文件存儲(chǔ)、文件同步、文件上傳、文件下載等,解決了大容量存儲(chǔ)和負(fù)載均衡的問題。本文將提供Java將文件上傳至FastDFS的示例代碼,需要的參考一下2022-02-02Java基于jdbc連接mysql數(shù)據(jù)庫操作示例
這篇文章主要介紹了Java基于jdbc連接mysql數(shù)據(jù)庫操作,結(jié)合完整實(shí)例形式分析了java使用jdbc連接mysql數(shù)據(jù)庫的具體步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-07-07