2015-10-17 40 views
2

我有一個非常長的字符串,看起來類似於此。String.replace()並非取代所有的發生

355,356,357,358,359,360,361,382,363,364,365,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,368,369,313,370,371,372,373,374,375,376,377,378,379,380,381,382,382,382,382,382,382,383,384,385,380,381,382,382,382,382,382,386,387,388,389,380,381,382,382,382,382,382,382,390,391,380,381,382,382,382,382,382,392,393,394,395,396,397,398,399,.... 

當我嘗試使用下面的代碼從字符串中刪除數字382。

String str = "355,356,357,358,359,360,361,382,363,364,365,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,368,369,313,370,371,372,373,374,375,376,377,378,379,380,381,382,382,382,382,382,382,383,384,385,380,381,382,382,382,382,382,386,387,388,389,380,381,382,382,382,382,382,382,390,391,380,381,382,382,382,382,382,392,393,394,395,396,397,398,399,...." 
str = str.replace(",382,", ","); 

但似乎並非所有的事件都被取代。最初發生3000次以上的字符串在更換後仍有約630次出現。

String.replace()的能力有限嗎?如果是這樣,是否有可能實現我所需要的方式?

回答

3

需要更換後面的逗號以及(如果存在的話,它不會如果列表中最後一個):

str = str.replaceAll("\\b382,?", ""); 

\b字的邊界,以防止匹配"-,1382,-"

以上將轉換:

382,111,382,1382,222,382 

到:

111,1382,222 
3

我認爲這個問題是382後之前,你的第一個參數replace(),特別是逗號(,)如果您有「382382383」,你將只匹配內「382」,並留下最初的一個落後。嘗試:

str.replace("382,", ""); 

雖然這將無法匹配「382」在最後,因爲它後面沒有逗號。

完整的解決方案可能涉及二方法調用這樣的:

str = str.replace("382", ""); // Remove all instances of 382 
str.replaceAll(",,+", ","); // Compress all duplicates, triplicates, etc. of commas 

這結合了兩種方法:

str.replaceAll("382,?", ""); // Remove 382 and an optional comma after it. 

注:無論是過去的兩種方法會留下拖逗號,如果382是在結束。

+1

這怎麼會發生630次?此外,你會得到兩個逗號背靠背。 – Zarwan

+0

我們必須看到這些數據,但我猜測有682個630個實例與其自身相鄰。你對這個逗號背對背。我相應地調整了我的答案。 – dave

+2

'replace()'不使用正則表達式;它使用純文本搜索 – Bohemian

1

試試這個

str = str.replaceAll(",382,", ","); 
+2

爲什麼這個工作會更好? 'replace'和'replaceAll'與這個參數沒有區別。 – resueman

1

首先,去掉前面的逗號在匹配的字符串。然後,通過使用java正則表達式用逗號替換逗號來刪除重複的逗號。

String input = "355,356,357,358,359,360,361,382,363,364,365,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,368,369,313,370,371,372,373,374,375,376,377,378,379,380,381,382,382,382,382,382,382,383,384,385,380,381,382,382,382,382,382,386,387,388,389,380,381,382,382,382,382,382,382,390,391,380,381,382,382,382,382,382,392,393,394,395,396,397,398,399"; 
    String result = input.replace("382,", ","); // remove the preceding comma 
    String result2 = result.replaceAll("[,]+", ","); // replace duplicate commas 

    System.out.println(result2); 
1

戴維已經說了,問題是,你的模式重疊。在串"...,382,382,..."有兩次出現",382,"

"...,382,382,..." 
    -----   first occurrence 
     -----  second occurrence 

這兩個出現在逗號重疊,因此Java的只能更換其中的一個。發現事件時,它不會看到您將模式替換爲什麼,因此當替換第一個事件被替換爲逗號時,不會看到生成新事件",382,"

如果你的數據是已知不包含超過3個位數的數字,那麼你可以做:

str.replace("382,", ""); 

,然後在年底作爲特殊情況處理事件。但是如果你的數據可以包含大數字,那麼"...,1382,..."將被"...,1,..."取代,這可能不是你想要的。

這裏有沒有上述問題,有兩種解決方案:直到不再出現任何變化

首先,簡單地重複更換:

String oldString = str; 
str = str.replace(",382,", ","); 
while (!str.equals(oldString)) { 
    oldString = str; 
    str = str.replace(",382,", ","); 
} 

之後,你將不得不處理可能發生在字符串的末尾。

第二,如果你對Java 8,你可以做更多的工作自己,用Java流:

str = Arrays.stream(str.split(",")) 
    .filter(s -> !s.equals("382")) 
    .collect(Collectors.joining(",")); 

這首先在分割字符串「」,然後篩選出哪些是相等的所有字符串到「382」,然後將剩餘的字符串再次與「,」連接在一起。

(這兩個代碼片段都未經測試。)

相關問題