替换字符串的多次出现,但第一个除外

时间:2020-01-25 23:29:21

标签: java regex

我有一个字符串,在其中我希望除去第一次出现的所有§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)

但是,这看起来不太好,并且仅在字符串之间包含一个或两个字符时才有效。有没有更好的方法来实现这一目标?性能如何?

2 个答案:

答案 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()