在 Java 中查找字符串模式

Find String Pattern in Java

我想在以下字符串中找到一个模式:

NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTCNATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGGGGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGNNGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNNCNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGGNTGNNNNNNNNNNNNNNNNNNNNNNNNNNN

模式必须包含至少 4 个相邻字符,'N' 除外。

例如在这个字符串中,

NNNNNTTCAANGGGACGG.....

我可以得到 "TTCA" "TCAA" "GGGA", "GGAC" , "GACG", "ACGG" ...

我想找到与模式匹配的任何可能的字符串。

哪种方法最适合这个?

我可以创建一个数组并读取每个字符。 不过,有没有更好的设计和思路呢?

谢谢!

您可以使用 PatternMatcher 来完成。使用 Matcher#find(int index) 可以从指定的索引开始匹配。给定的 Pattern 被匹配,并且 Matcher 被重置为从上一个匹配位置 + 1 开始,所以没有子串被遗漏。

代码

public static void main(String[] arguments) throws FileNotFoundException {
    Matcher m = Pattern.compile("[A-M|O-Z]{4}").matcher(
            "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTT"
                    + "CAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTC"
                    + "NATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGG"
                    + "GGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGN"
                    + "NGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNN"
                    + "CNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGG"
                    + "NTGNNNNNNNNNNNNNNNNNNNNNNNNNNN");

    int index = 0;
    while (m.find(index)) {
        index = m.start() + 1;
        System.out.println(m.group());
    }
}

输出

TTCA
TCAA
GGGA
GGAC
GACG
ACGG
CGGA
GGAG
GAGC
AGCG
GCGG
CGGG
GGGT
GGTG
GTGC
GAGG
AGGA
GGAG
GCGC
CGCT
GCTT
CTTC
TTCG
TCGA
CGAC
GACA
ACAG
CAGC
AGCG
GCGA
CGAC
GACG
ACGT
CGTG
GTGG
TGGG
GGGG
GGGG
GGGA
GGAG
GAGT
GGCG
GCGG
CGGT
GGTG
GTGA
TGAC
GAGC
AGCT
GGGC
GGCG
GCGG
CGGC
GGCC
GCCT
CTGG
TGGA
GGAA
GAAC
AACA
ACAG
CAGC
AGCC
GCCA
CCAG
CAGA
AGAA
GAAG
AAGG
AGGA
GGAC
TCCT
CCTG
CTGG
TGGA
GTGG
TGGA
GGAC
GACA
TGCA
GCAG
CAGA
AGAC
GACA
ACAC
CACA
ACAA
CAAC
AACT
ACTA
CTAC
TACG
ACGG
CGGG
GGGG

一种方法是使用 Java 8 流并进行一些过滤、映射和收集:

String str = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTCNATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGGGGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGNNGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNNCNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGGNTGNNNNNNNNNNNNNNNNNNNNNNNNNN";
final char[] src = str.toCharArray();

final int len = 4;
final int ch = 'N';
final List<String> collect =
        IntStream.range(0, str.length() - len)
                .filter(offset -> IntStream
                        .range(offset, offset + len)
                        .noneMatch(i -> src[i] == ch))
                .boxed()
                .map(i -> str.substring(i, i + len))
                .collect(Collectors.toList());

System.out.println(collect); // [TTCA, TCAA, GGGA, GGAC, ....

这是我的正则表达式过敏解决方案。感谢@Niels Billen 提供了很好的源字符串格式。

public static void main(String[] args) {
     String string =  "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTT"
                        + "CAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTC"
                        + "NATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGG"
                        + "GGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGN"
                        + "NGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNN"
                        + "CNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGG"
                        + "NTGNNNNNNNNNNNNNNNNNNNNNNNNNNN";

     for (String s: string.split("N")) {
         for (int i = 0 ; i <= s.length() - 4 ; i++) {
             System.out.println(s.substring(i, i + 4));
         }
     }
}