2015-10-17 168 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”,然后将剩余的字符串再次与“,”连接在一起。

(这两个代码片段都未经测试。)