將字符串中的數字替換成$D
但願將如下字符串中的數字替換爲$D字符
java
引用正則表達式
ab1cd2
app
咱們知道String有3個用於字符替換的方法,分別是:
spa
String replace(CharSequence target, CharSequence replacement):將字符串中出現的target替換成replacement;.net
String replaceAll(String regex, String replacement):regex是一個正則表達式,將字符串中匹配的子字符串替換爲replacement;設計
String replaceFirst(String regex, String replacement):和replaceAll(..)相似,只不過只替換第一個出現的地方。orm
因爲咱們但願全部替換,所以使用以下方法:
代碼1:StringReplaceTest
事件
Java代碼 開發
public class StringReplaceTest { 字符串
public void testReplace(){
String str = "ab1cd2";
System.out.println(str.replaceAll(str, "$D"));
}
}
小小代碼現詭異異常
運行StringReplaceTest,控制檯卻沒有返回正確的結果,而是拋出以下的異常:
引用
java.lang.IllegalArgumentException: Illegal group reference
at java.util.regex.Matcher.appendReplacement(Matcher.java:713)
at java.util.regex.Matcher.replaceAll(Matcher.java:813)
at java.lang.String.replaceAll(String.java:2189)
at com.hsit.euler.qform.engine.jdbc.StringReplaceTest.testReplace(StringReplaceTest.java:17)
比較詭異吧,難道是JDK的BUG???
剝絲入繭,原來如此
其實String的replaceAll()及replaceFirst()方法內部都是調用java.util.regex.Matcher的String replaceAll(String replacement)方法的。讓咱們把剛纔的詫異放在一邊,好好看下這個方法的Javadoc,掐頭去尾,主要是這段:
引用
* <p> Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in
* the replacement string may cause the results to be different than if it
* were being treated as a literal replacement string. Dollar signs may be
* treated as references to captured subsequences as described above, and
* backslashes are used to escape literal characters in the replacement
* string.
原來是咱們的替換目標串中包含了$這個特殊的字符,由於替換串使用這個引用正則表達式匹配的組,$0表明匹配項,$1表明第1個匹配分組,$1表明第2個匹配分組--終於真相大白了,是咱們闖了雷區了
來看一個例子加深一個印象:
Java代碼
public void testReplace2(){
String str = "劉備是張飛的小弟";
System.out.println(str.replaceAll("(劉備)是(張飛)", "$2是$1"));
//=>張飛是劉備的小弟
}
李鬼出來,李逹進去
李鬼現形,處理起來天然簡單:
Java代碼
public void testReplace(){
String str = "ab1cd2";
System.out.println(str.replaceAll(str, "\\$D"));
//=>ab$Dcd$D
}
小評一下
若是JDK能夠再分析一下$,將$N即N是數字時纔對其進行特殊處理,不然就不當成特殊字符,是否是更好一些呢?
也許這樣並很差,必須這樣形成Matcher方法爲了這個小几率事件作不少複雜的檢查,結果是得不償失的。仍是遇到特殊字符報異常,讓開發者去處理更好些,這是28原來取捨得當的一個API設計。既然$是特殊字符,開發者繞過便可。