You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从含连续重复字符的字符串中仅保留指定数量的重复字符?

嘿,这个问题我之前刚折腾过!你现在的写法只能固定N=2,核心原因是把正则里的重复次数和替换字符串都写死了,只要改成动态生成正则和替换内容,就能适配任意N值啦,我给你两种解决方案:

方法一:用动态生成的正则+replaceAll(简洁高效)

这种方法完美匹配你的需求,思路是:只匹配那些连续重复次数超过N的字符序列,然后把它们替换成正好N个该字符,而重复次数不足N的序列会被保留原样。

代码示例:

int N = 3; // 你可以改成任意非负整数,比如0、1、4等
String input = "fffooooobbbbaarrr";

// 动态构建正则:匹配一个字符后面跟至少N个相同字符(总长度≥N+1)
String regex = String.format("(\\w)\\1{%d,}", N);
// 动态构建替换字符串:重复N次捕获到的字符
String replacement = new String(new char[N]).replace("\0", "$1");

String result = input.replaceAll(regex, replacement);
System.out.println(result); // 输出:fffooobbbaarrr

逻辑拆解:

  • 正则(\\w)\\1{N,}:(\\w)捕获单个单词字符,\\1{N,}表示这个字符至少重复N次,所以整个匹配的是连续N+1个及以上的相同字符。
  • 替换字符串是N个$1(也就是捕获到的字符重复N次),这样就把超长的重复序列截断成正好N个,而短序列不会被匹配,自然保留原样。
  • 特殊情况处理:
    • 当N=0时,替换字符串是空,正则会匹配所有连续字符(包括单个字符),最终输出空字符串。
    • 当N=1时,正则匹配连续2个及以上的相同字符,替换成单个字符,正好得到fobar。

方法二:用Matcher自定义替换(更灵活)

如果你需要处理非单词字符(比如空格、符号),或者想更精细控制替换逻辑,可以用Matcher的appendReplacement方法,逐个处理每个匹配到的连续字符序列:

int N = 2;
String input = "fffooooobbbbaarrr";
// 匹配任意连续重复的单词字符,改成"(.\\1*)"可以匹配所有字符
Pattern pattern = Pattern.compile("(\\w)\\1*");
Matcher matcher = pattern.matcher(input);
StringBuffer resultSb = new StringBuffer();

while (matcher.find()) {
    String matchedSeq = matcher.group();
    // 取序列的前N个字符,如果序列长度小于N就取全部
    String replacement = matchedSeq.substring(0, Math.min(matchedSeq.length(), N));
    // 注意用quoteReplacement避免替换字符串里的特殊字符生效
    matcher.appendReplacement(resultSb, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(resultSb);

System.out.println(resultSb.toString()); // 输出:ffoobbaarr

这种方法的好处是不依赖正则的量词逻辑,直接根据匹配到的序列长度动态生成替换内容,适用性更广。

为什么你原来的写法只能固定N=2?

你之前写的Pattern.compile("(\\w)\\1{2,}")和replaceAll("$1$1")都是写死了“匹配连续3个及以上的字符,替换成2个”,把其中的数字换成动态生成的N值,问题就解决啦~

内容的提问来源于stack exchange,提问作者anta40

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:26:55