在同一个字符串中使用多个正则表达式匹配得不到所需的结果

时间:2013-10-17 02:41:23

标签: java regex

我有一个独特的问题陈述,我必须使用三个字符对输入字符串执行正则表达式。例如如果我的输入为ABCDEFGHI,则BCD的模式搜索应该返回false,因为我将输入视为ABC+DEF+GHI,并且需要将我的正则表达式模式与这些三重字符进行比较。

同样,正则表达式模式DEF将返回true,因为它匹配其中一个三元组。使用此问题语句,假设我的输入为QWEABCPOIUYTREWXYZASDFGHJKLABCMNBVCXZASXYZFGH,并且我尝试获取以三元组ABC开头并以XYZ结尾的所有输出字符串。因此,在上面的输入中,我的输出应该是两个字符串:ABCPOIUYTREWXYZABCMNBVCXZASXYZ

另外,我必须将这些字符串存储在ArrayList中。以下是我的功能:

public static void newFindMatches (String text, String startRegex, String endRegex, List<String> output) {
    int startPos = 0;
    int endPos = 0;
    int i = 0;
    // Making sure that substrings are always valid
    while ( i < text.length()-2) {
        // Substring for comparing triplets
        String subText = text.substring(i, i+3);
        Pattern startP = Pattern.compile(startRegex);
        Pattern endP = Pattern.compile(endRegex);
        Matcher startM = startP.matcher(subText);
        if (startM.find()) {
            // If a match is found, set the start position
            startPos = i;
            for (int j = i; j < text.length()-2; j+=3) {
                String subText2 = text.substring(j, j+3);
                Matcher endM = endP.matcher(subText2);
                if (endM.find()) {
                    // If match for end pattern is found, set the end position
                    endPos = j+3;
                    // Add the string between start and end positions to ArrayList
                    output.add(text.substring(startPos, endPos));
                    i = j;
                }
            }               
        }
        i = i+3;

    }


}

在main中运行此功能,如下所示:

String input = "QWEABCPOIUYTREWXYZASDFGHJKLABCMNBVCXZASXYZFGH";
    String start = "ABC";
    String end = "XYZ";
    List<String> results = new ArrayList<String> ();
    newFindMatches(input, start, end, results);

    for (int x = 0; x < results.size(); x++) {
        System.out.println("Output String number "+(x+1)+" is: "+results.get(x));
    }

我得到以下输出:

Output String number 1 is: ABCPOIUYTREWXYZ
Output String number 2 is: ABCPOIUYTREWXYZASDFGHJKLABCMNBVCXZASXYZ

请注意,第一个字符串是正确的。但是,对于第二个字符串,程序再次从输入字符串的开头读取。相反,我希望程序在最后一个结束模式之后读取(即跳过第一个搜索和不需要的字符,如ASDFGHJKL,并且只应打印第二个字符串:ABCMNBVCXZASXYZ

感谢您的回复

1 个答案:

答案 0 :(得分:2)

这里的问题是当你找到你的结束匹配(for循环中的if语句)时,你不会停止for循环。因此,它一直在寻找更多的结束匹配,直到它达到for循环结束条件j&lt; text.length() - 2。当您找到匹配并处理它时,您应该使用“break;”结束循环。放下“休息”在i = j行之后。

请注意,从技术上讲,当前程序给出的第二个答案是正确的,也就是以ABC开头并以XYZ结尾的子字符串。您可能想重新考虑程序的正确输出。您可以通过在找到匹配时不设置i = j来适应这种情况,因此i的唯一递增是i = i + 3行,遍历三元组(并且不添加中断)。