模式matcher.group()超出范围异常

时间:2012-09-28 10:57:28

标签: java regex

我有字符串:

    String myString1 = "22223 2342 1 98 333 3 665"

    String myString2 = "22323 3 222 34 33 1 98"

我想只提取有1位数的值,然后是空格,然后只提取两位数。

    private static final Pattern p3DigitsGap = Pattern.compile(".*\\b\\d\\s\\d{2}\\b.*");

在上述两个字符串中,我想要提取“1 98”我不能只是在字符串末尾的任何一边用空格分割。

        Matcher matcher = p3DigitsGap.matcher(myString1);
        if (matcher.find()) {
            Log.i("Matcher found");
            while (matcher.find() == true) {
                Log.i("Matcher is true");
                String extract = matcher.group(1);
                Log.d("extract: " + extract);
            }
        }

如果我删除while循环,则永远不会填充字符串提取并抛出超出范围的异常。我在while循环中添加了matcher.find()不等于true。

我尝试将我的模式换成:

    Pattern p3DigitsGap = Pattern.compile("[^0-9a-z]\\d\\s\\d{2}[^0-9a-z]");

我认为使用。* \\ b可能会导致问题,但我得到的结果相同。

请有人帮我理解我哪里出错了。

提前致谢。

答案编辑:我将Reimeus的答案标记为正确,因为它通过使用具有上述正则表达式的组来工作。另请参阅Tim Pietzcker的答案,以获得改进原始正则表达式的替代解决方案。

3 个答案:

答案 0 :(得分:2)

最好在匹配时使用groups,因此您可以使用:

Pattern p3DigitsGap = Pattern.compile(".*\\b(\\d\\s\\d{2})\\b.*");
Matcher matcher = p3DigitsGap.matcher(myString1);
if (matcher.find()) {
   Log.i("Matcher is true");
   String extract = matcher.group(1);
   Log.d("extract: " + extract);
}

答案 1 :(得分:1)

两个问题:

  • 您的正则表达式中没有任何捕获组,因此任何匹配项的最高有效组将为.group(0)(整个匹配)。

  • 您的示例字符串只匹配一次,但您调用matcher.find()两次,因此第二次调用(在while循环中)不返回任何匹配项。

试试这个:

Pattern p3DigitsGap = Pattern.compile("\\b\\d\\s\\d{2}\\b");
Matcher matcher = p3DigitsGap.matcher(myString1);
if (matcher.find()) {
    Log.i("Matcher found");
    String extract = matcher.group(0);
    Log.d("extract: " + extract);
}

答案 2 :(得分:1)

您没有定义任何群组,您可以使用( and )定义群组,我认为您的代码应该是:

 private static final Pattern p3DigitsGap = Pattern.compile("\\b\\d\\s\\d{2}\\b");
 Matcher matcher = p3DigitsGap.matcher(myString1);
 while (matcher.find()) {
   Log.i("Matcher is true");
   String extract = matcher.group(0);
   Log.d("extract: " + extract);
 }