如何使用 Java Regex 查找字符串中的所有重复字符序列?

Posted

技术标签:

【中文标题】如何使用 Java Regex 查找字符串中的所有重复字符序列?【英文标题】:How do I use Java Regex to find all repeating character sequences in a string? 【发布时间】:2012-05-04 11:40:01 【问题描述】:

使用 Java 和 Regex 解析随机字符串以查找重复序列。

考虑字符串:

aaabbaaacccbb

我想找到一个正则表达式,它会在上面的字符串中找到所有匹配项:

aaabbaaacccbb
^^^  ^^^

aaabbaaacccbb
   ^^      ^^

什么是正则表达式,它将检查字符串中是否存在任何重复的字符序列并返回这些重复字符的组,例如组 1 = aaa 和组 2 = bb。另请注意,我使用了示例字符串,但任何重复字符都是有效的: 罗恩乔乔 ... ... ,, ,,...,,

【问题讨论】:

似乎使用像this这样的基于字典的字符串搜索算法会更好,因为你一开始不知道模式。 重复序列是否需要连续? “RonBobRonJoe”是否应该返回“Ron”? RonBobRonBobAbeRonBobRonBobAbeXXYYXY 应该返回什么? “重复字符序列”与“重复字符序列”的意思是一样的吗? 【参考方案1】:

这样做:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test 
    public static void main(String[] args) 
        String s = "aaabbaaacccbb";
        find(s);
        String s1 = "RonRonRonJoeJoe .... ,,,,";
        find(s1);
        System.err.println("---");
        String s2 = "RonBobRonJoe";
        find(s2);
    

    private static void find(String s) 
        Matcher m = Pattern.compile("(.+)\\1+").matcher(s);
        while (m.find()) 
            System.err.println(m.group());
        
    

输出:

aaa
bb
aaa
ccc
bb
RonRonRon
JoeJoe
....
,,,,
---

【讨论】:

实际上,这不起作用:如果您对 RonRonJoeJoe 运行它,它不会打印任何内容。 @ReverendGonzo 好的,我在帖子中错过了。我现在通过在 \\w 之后添加 + 来修复它 @ReverendGonzo 那应该是什么输出?没有重复序列,因此它不匹配任何东西 “罗恩”重复。我的印象是它们不需要连续。 @ReverendGonzo 好的,我明白你的意思了。我实际上有相反的感觉,他们应该是连续的。 OP 必须澄清这一点。【参考方案2】:

以下内容应适用于所有要求。它实际上是这里的几个答案的组合,它会打印出字符串中其他任何地方重复的所有子字符串。

我将其设置为仅返回至少 2 个字符的子字符串,但可以通过将正则表达式中的“2,”更改为“+”轻松将其更改为单个字符。

public static void main(String[] args)

  String s = "RonSamJoeJoeSamRon";
  Matcher m = Pattern.compile("(\\S2,)(?=.*?\\1)").matcher(s);
  while (m.find())
  
    for (int i = 1; i <= m.groupCount(); i++)
    
      System.out.println(m.group(i));
    
  

输出: 罗恩 山姆 乔

【讨论】:

但是你如何计算每个字符串在文件中的元素数量,为什么它的 kmer 总是 3?【参考方案3】:

您可以使用这个基于positive lookahead 的正则表达式:

((\\w)\\2+)(?=.*\\1)

代码:

String elem = "aaabbaaacccbb";
String regex = "((\\w)\\2+)(?=.*\\1)";
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(elem);
for (int i=1; matcher.find(); i++)
System.out.println("Group # " + i + " got: " + matcher.group(1));

输出:

Group # 1 got: aaa
Group # 2 got: bb

【讨论】:

【参考方案4】:

这似乎有效,尽管它也给出了子序列:

(公平地说,这是根据 Guillame 的代码构建的)

public static void main(final String[] args) 
    // final String s = "RonRonJoeJoe";
    // final String s = "RonBobRonJoe";
    final String s = "aaabbaaacccbb";

    final Pattern p = Pattern.compile("(.+).*\\1");

    final Matcher m = p.matcher(s);
    int start = 0;
    while (m.find(start)) 
        System.out.println(m.group(1));
        start = m.toMatchResult().end(1);
    

【讨论】:

【参考方案5】:

您可以忽略重叠。

// overlapped 1 or more chars
(?=(\w1,).*\1)
// overlapped 2 or more chars
(?=(\w2,).*\1)
// overlapped 3 or more chars, etc ..
(?=(\w3,).*\1)

或者,你可以消费(非重叠)..

// 1 or more chars
(?=(\w1,).*\1) \1
// 2 or more chars
(?=(\w2,).*\1) \1
// 3 or more chars, etc ..
(?=(\w3,).*\1) \1

【讨论】:

以上是关于如何使用 Java Regex 查找字符串中的所有重复字符序列?的主要内容,如果未能解决你的问题,请参考以下文章

Java Regex:查找带转义的单引号文本

PL/SQL Regex 查找最后一个数字并拆分

Java如何替换所有指定(出现)的字符串?

python 使用Regex查找字符串中的匹配项

使用 Java Regex,如何检查字符串是不是包含集合中的任何单词?

在Javascript中查找不包含/ indexOf / Regex的字符串中的子字符串