當前位置:
首頁 > 知識 > String.replaceAll方法,正則妙用

String.replaceAll方法,正則妙用

我通常是不太關心代碼的具體實現的,因為我的開發語言很雜,傾向於一些最簡單通用的方式去解決。今兒不小心在群里看到一位朋友發了下面的java代碼,感覺自己還是很局限很無知的:

通過輸出可以看到,這段代碼的作用是把駝峰命名格式的字元串替換成下劃線分割,這個功能比較簡單,但是吸引我的卻是他的代碼。

createTime.replaceAll(([A-Z] ),_$1)

這行代碼簡單的很,就是調用了String類的replaceAll方法,方法的第一個參數是正則表達式,第二個參數是將要被替換成的新值。

讓我驚奇的是他代碼中,replaceAll的第二個參數,也就是JDK文檔中名為replacement的參數,竟然是_$1。這是什麼鬼?還支持類似佔位符這樣的東西?我一直都不知道。

問題探索

由於之前研究過一段正則表達式,通過觀察replaceAll的第一個參數([A-Z] ),我猜想,這個應該是用到了正則表達式的分組,對應JDK中,就是java.util.regex.Matcher類的group()方法。

在Linux的Sed命令上,就使用進行了一些替換,道理應該是相通的。

於是看了下String.replaceAll方法是如何實現的。JDK:

哦,原來它底層就是用了Matcher,只不過用的是Matcher自己的replaceAll方法。

去看它的文檔,這個方法的參數果然有鬼,看下面實現代碼。

裡面關鍵的部分就是文檔中說的appendReplacement方法,然後可以看到詳細的描述文檔。

看到這裡明白了,原來這個方法的replacement參數可以通過$字元來指代Matcher通過正則匹配得到的分組,支持name和number 兩種方式,這裡對應的就是Matcher類的group(name)和group(int)兩個方法。

結論

1、String的replaceAll方法實際上是通過java.util.regex.Matcher類的replaceAll()方法實現的。

2、java.util.regex.Matcher類的replaceAll方法又是通過調用appendReplacement方法實現替換邏輯

3、Matcher類的appendReplacement方法的replacement參數支持通過$符號來指代Matcher匹配的分組

下面這串代碼,就是使用Matcher類分組的一個最佳實踐。

group(0)表示整個字元串

group(1)表示第一個匹配的,上面的例子中就是(我的手機號碼是:([0-9]{11}))部分

group(2)表示第二個匹配的,上面的例子中就是([0-9]{11})部分

使用分組可以用來提取字元串中的目標字元串值,很好用!

幾個例子

下面是幾個例子,大家可以觸類旁通。

駝峰轉下劃線命名

下劃線轉駝峰

這個稍微麻煩點,是模仿者Matcher.replaceAll方法寫的。

public static String underlineToCamel(String underlineName) {

Matcher matcher = Pattern.compile((_[a-z]{1})).matcher(underlineName);

StringBuffer result = new StringBuffer();

while (matcher.find()) {

String replacement = matcher.group(1);

matcher.appendReplacement(result, replacement.replace(_, ).toUpperCase());

}

matcher.appendTail(result);

return result.toString();

}

另外,Mybatis Generator插件源碼中的也提供了類似方法(JavaBeansUtil.getCamelCaseString),這裡做了下簡單修改

沒有複雜的正則參與,速度顯而快了不少。

End

看一些優秀的開源代碼,確實能夠了解到一些實用的技巧。這比起自己費勁心力重複製造一些輪子,要高效的多。時間要用在刀刃上,但不是用來切豆腐。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

分享:更好的SQL查詢如何做到
如何寫出 沒有 BUG 的代碼

TAG:千鋒JAVA開發學院 |