2011-03-23 69 views
10

我知道兩種方式替換全部字符串中子字符串的出現。替換字符串中所有出現的子字符串 - 在Java中更高效?

正則表達式的方法(假設 「子到被替換」 不包括正則表達式特殊字符):

String regex = "substring-to-be-replaced" + "+"; 
Pattern scriptPattern = Pattern.compile(regex); 
Matcher matcher = scriptPattern.matcher(originalstring); 
newstring = matcher.replaceAll("replacement-substring"); 

的與string.replace()方法:

newstring = originalstring.replace("substring-to-be-replaced", "replacement-substring"); 

哪兩者更有效率(以及爲什麼)?

是否有比上述兩種更有效的方法?

+2

什麼叫高效呢?更少的內存消耗?處理器時間更少? – 2011-03-23 15:27:39

+0

考慮到'regex'會出現在'substring-to-be-replace +'中,最終只允許多個'd',它們甚至不會在同一事物附近進行任何操作。 – 2011-03-23 15:28:55

+0

@Vladimir Ivanov更快。 – 2011-03-23 15:31:40

回答

12

String.replace()在下面使用正則表達式。

public String replace(CharSequence target, CharSequence replacement) { 
     return Pattern.compile(target.toString(), Pattern.LITERAL) 
      .matcher(this).replaceAll(
       Matcher.quoteReplacement(replacement.toString())); 
    } 

是否有更有效的方法比上面描述的兩個?

有給你操作上實現支持例如,通過一個數組,而不是一成不變的String類(因爲string.replace創建在每次調用一個新)。參見例如StringBuilder.replace()

編譯正則表達式相當於很多的開銷,在觀察Pattern source code時很明顯。幸運的是,Apache在StringUtils.replace()中提供了另一種方法,根據source code(行#3732),它非常有效。

+0

您指向的字符串實現使用'Pattern'作爲替代方法。 – Jeremy 2011-03-23 15:33:09

+0

@JohanSjöbergStringBuilder.replace()與String.replace()不同,因爲它接受開始和結束索引,而不是「將被替換的字符串」。 – 2011-03-23 16:33:49

+0

@Regex菜鳥,正是這是使它更高效的一部分 – 2011-03-23 16:41:27

1

代替使用string s,這是不可變的,使用char陣列或一些其它可變類型(如StringBufferStringBuilder)的。

+0

感謝您的提示。你能詳細解釋一下嗎?我知道使用replace()時,originalstring不會被修改。你能提供一個例子嗎? – 2011-03-23 15:30:41

+0

嘗試使用[StringBuffer](http://download.oracle.com/javase/1.4.2/docs/api/java/lang/StringBuffer.html)。 – Davidann 2011-03-23 15:32:45

+1

在非併發情況下,'StringBuilder'會更合適。 – Jeremy 2011-03-23 15:34:30

0

不應該比較replaceAll 2次嗎?但是,對於單個調用而言,它幾乎不可測量。你會做數百萬次比較嗎?

然後,我希望'編譯'更快,但只有,如果你不使用沒有任何模式規則的常量字符串。

寫微基準測試的問題在哪裏?或者查看來源。

1

沒有做任何分析或基準測試,我認爲這是一個相當安全的選擇,如果你不需要正則表達式魔法,那麼正則表達式解析器的開銷(你會得到的不管是什麼,在內存條款以及CPU使用情況)會比另一端花費的成本要高得多。

2

下面是從的OpenJDK的source code

public String replace(CharSequence target, CharSequence replacement) { 
    return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
     this).replaceAll(Matcher.quoteReplacement(replacement.toString())); 
} 
+1

因此,事實證明,如果需要經常替換相同的字符串,使用預編譯的正則表達式替換allAll會更好。 – Ingo 2011-03-23 16:15:20

相關問題