用正则表达式替换重复的字符串模式

4

我需要用每个基本构建单元替换单词中的重复模式。例如,我有字符串"TATATATA",我想用"TA"替换它。此外,我可能会替换多于2次重复以避免替换正常单词。

我正在尝试使用Java的replaceAll方法来完成此操作。


3
你的代码/正则表达式在哪里? - TheLostMind
请展示你的代码。 - Sanjeev
1
你的意思是指任何在字符串中可能存在的重复字符,例如TATATATA、YTYTYT或ABCABCABC? - Kenneth Clark
可以使用正则表达式的“向前查看”、“向后查看”、String#contains()、String#indexOf()等方法来实现此功能。但请展示您的努力。 - TheLostMind
1
看我的回答,我想我懂了。 - MightyPork
显示剩余8条评论
3个回答

9
我认为您需要这个(适用于任何重复字符串的长度):
String result = source.replaceAll("(.+)\\1+", "$1")

或者,为了优先考虑长度更短的匹配项:

String result = source.replaceAll("(.+?)\\1+", "$1")

它首先匹配一组字母,然后再次匹配它(在匹配模式内使用反向引用)。我尝试了一下,似乎效果不错。


示例

String source = "HEY HEY duuuuuuude what'''s up? Trololololo yeye .0.0.0";

System.out.println(source.replaceAll("(.+?)\\1+", "$1"));

// HEY dude what's up? Trolo ye .0

1

在这里最好使用Pattern而不是.replaceAll()。例如:

private static final Pattern PATTERN 
    = Pattern.compile("\\b([A-Z]{2,}?)\\1+\\b");

//...

final Matcher m = PATTERN.matcher(input);
ret = m.replaceAll("$1");

编辑:例子:

public static void main(final String... args)
{
    System.out.println("TATATA GHRGHRGHRGHR"
        .replaceAll("\\b([A-Za-z]{2,}?)\\1+\\b", "$1"));
}

这将打印:

TA GHR

没起作用,打印了整个字符串。谢谢你的回答! - Michael
是的,确实是这样,我尝试在末尾添加了一个额外的字符,比如“TATATAT”。 - Michael

1

既然你要求一个正则表达式的解决方案:

(\\w)(\\w)(\\1\\2){2,};

(\w)(\w):匹配每一对连续的单词字符((.)(.)会捕获任何类型的连续字符对),并将它们存储在捕获组 1和2中。 (\\1\\2) 在这些组中的字符再次立即重复时匹配,而{2,} 则是当它重复两次或更多次时匹配({2,10}是在重复一次以上但少于十次时匹配)。

String s = "hello TATATATA world";    
Pattern p = Pattern.compile("(\\w)(\\w)(\\1\\2){2,}");
Matcher m = p.matcher(s);
while (m.find()) System.out.println(m.group());
    //prints "TATATATA"

我担心它只打印第一个字母。感谢您的回答! - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接