[英]String.replace() not replacing all occurrences
我有一个很长的字符串,看起来与此类似。
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() 的能力是否有限? 如果是这样,是否有可能实现我需要的方法?
我认为问题是你的第一个参数replace()
,特别是382之前和之后的逗号(,)。如果你有“382,382,383”,你将只匹配内部“,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在结尾,则后两种方法都会留下尾随逗号。
您还需要替换尾随逗号(如果存在,如果列表中的最后一个则不会):
str = str.replaceAll("\\b382,?", "");
注意\\b
字边界以防止匹配"-,1382,-"
。
以上将转换:
382,111,382,1382,222,382
至:
111,1382,222
尝试这个
str = str.replaceAll(",382,", ",");
首先,删除匹配字符串中的前一个逗号。 然后,通过使用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);
正如戴夫已经说过的,问题是你的模式重叠了。 在字符串"...,382,382,..."
有两次出现",382,"
:
"...,382,382,..."
----- first occurrence
----- second occurrence
这两个匹配项在逗号处重叠,因此Java只能替换其中一个。 当找到事件时,它还没有看到你用什么替换模式,因此当替换第一个匹配项被逗号替换时",382,"
它不会看到新的",382,"
出现。
如果您的数据已知不包含超过3位数的数字,那么您可能会:
str.replace("382,", "");
然后作为特例处理最后的事件。 但是如果你的数据可以包含大数字,那么"...,1382,..."
将被"...,1,..."
取代"...,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”的字符串,然后将剩余的字符串再次与“,”之间连接起来。
(两个代码段都未经过测试。)
传统方式:
String str = ",abc,null,null,0,0,7,8,9,10,11,12,13,14";
String newStr = "", word = "";
for (int i=0; i<str.length(); i++) {
if (str.charAt(i) == ',') {
if (word.equals("null") || word.equals("0"))
word = "";
newStr += word+",";
word = "";
} else {
word += str.charAt(i);
if (i == str.length()-1)
newStr += word;
}
}
System.out.println(newStr);
输出:,abc,,,,,7,8,9,10,11,12,13,14
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.