我有一个字符串,在其中我希望除去第一次出现的所有§a
,§b
和§c
也是这样。例如:
§ah§ae§al§al§bo §bw§bo§br§bl§bd
应该变成§ahell§bo world
。
在我的情况下,这些字符串之间始终始终只有一个或两个字符,从而产生以下正则表达式:
(((?<=§a.)|(?<=§a..))§a)|(((?<=§b.)|(?<=§b..))§b)|(((?<=§c.)|(?<=§c..))§c)
但是,这看起来不太好,并且仅在字符串之间包含一个或两个字符时才有效。有没有更好的方法来实现这一目标?性能如何?
答案 0 :(得分:1)
如果不一定要使用纯正则表达式replaceAll(regex, replacement)
解决方案,则可以使用appendReplacement
循环和Set
来跟踪每个匹配的子字符串的第一个实例。
Java 1.4+解决方案:
String input = "§ah§ae§al§al§bo §bw§bo§br§cl§cd";
Set<String> first = new HashSet<>();
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("§[abc]").matcher(input);
while (m.find())
if (! first.add(m.group()))
m.appendReplacement(buf, "");
String result = m.appendTail(buf).toString();
System.out.println(result);
Java 9+解决方案:
Set<String> first = new HashSet<>();
String result = Pattern.compile("§[abc]").matcher(input)
.replaceAll(mr -> first.add(mr.group()) ? "$0" : "");
输出
§ahell§bo wor§cld
答案 1 :(得分:0)
使用String.indexOf(“§a”)然后使用String.replace(“§a”,“”)对该字符后面的所有内容都非常容易。
可能占用更多的内存,但是我想您真的不需要高效的内存解决方案吗?
无论如何,无论如何它都将起作用,因此,如果没有其他效果,则可以这样做(即使使用3个字符串会使它更加混乱)。
要获取没有第一次出现的String,只需使用String.substring()和indexOf()