2015-06-07 68 views
1

我試圖取代String第一次出現的匹配我正則表達式,而迭代的出現次數是這樣的:拋出:IllegalArgumentException:非法組引用而replaceFirst

(此代碼是非常簡單的,所以不要試圖找到一些它更大的意義上)

Matcher tagsMatcher = Pattern.compile("\\{[sdf]\\}").matcher(value); 

int i = 0; 
while (tagsMatcher.find()) { 
    value = value.replaceFirst("\\{[sdf]\\}", "%" + i + "$s"); 
    i++; 
} 

我越來越IllegalArgumentException: Illegal group reference在執行replaceFirst。爲什麼?

+1

爲每一場比賽,它會做替換。那麼replaceFirst有什麼需要? –

+1

根據您的代碼,您應該使用'matcher.appendReplacement'示例:http://stackoverflow.com/a/19645633/1393766 http://stackoverflow.com/a/25081783/1393766 – Pshemo

回答

0

您需要轉義美元符號。

value = value.replaceFirst("\\{[sdf]\\}", "%" + i + "\\$s"); 

非法組參考錯誤的發生主要是因爲試圖引用一個真正不存在的組。

+0

真的...似乎問題不是正則表達式相關:) –

+0

我不知道'$ s'如何指的是一個組。認爲我錯了.. –

2

replacement部分replaceFirst(regex,replacement)可以包含對regex匹配的組的引用。要做到這一點,利用

  • $x語法,其中x是整數,表示羣號,
  • ${name}其中name是因爲這種能力$的命名組(?<name>...)

的名稱被視爲特殊字符在replacement,所以如果你想使$文字你需要

  • \replaceFirst(regex,"\\$whatever")
  • 還是讓Matcher逃生爲你使用Matcher.quote方法replaceFirst(regex,Matcher.quote("$whatever"))

,但你不應該使用

value = value.replaceFirst("\\{[sdf]\\}", "%" + i + "\\$s"); 

內循環,因爲每次你做它逃生,你需要遍歷整個字符串以找到你想要替換的部分,所以每次你需要從頭開始時,效率非常低。

正則表達式引擎在matcher.appendReplacement(StringBuffer, replacement)matcher.appendTail(StringBuffer)的形式中爲此效率低下提供瞭解決方案。

  • appendReplacement方法也加入到StringBuffer的所有數據,直到當前的比賽,並讓您指定要落實到位的正則表達式部分匹配
  • appendTail增加了其存在後,最後匹配的部分
部分

所以,你的代碼應該看起來更像

StringBuffer sb = new StringBuffer(); 
int i = 0; 

Matcher tagsMatcher = Pattern.compile("\\{[sdf]\\}").matcher(value); 
while (tagsMatcher.find()) { 
    tagsMatcher.appendReplacement(sb, Matcher.quoteReplacement("%" + (i++) + "$s")); 
} 
value = sb.toString(); 
2

特殊字符$可以處理簡單的方式。檢查下面的例子

public static void main(String args[]){ 
     String test ="Other company in $ city "; 
     String test2 ="This is test company "; 
     try{ 
      test2= test2.replaceFirst(java.util.regex.Pattern.quote("test"), Matcher.quoteReplacement(test)); 
      System.out.println(test2); 
      test2= test2.replaceAll(java.util.regex.Pattern.quote("test"), Matcher.quoteReplacement(test)); 
      System.out.println(test2); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

輸出:

This is Other company in $ city company 
This is Other company in $ city company 
相關問題