Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matcher.group throws IndexOutOfBoundsException Exception

I've below code and in which i am trying to print all the matches in a String using Matcher.group().

public static void main(String[] args) {
        String s = "foo\r\nbar\r\nfoo"
                + "foo, bar\r\nak  = "
                + "foo, bar\r\nak  = "
                + "bar, bar\r\nak  = "
                + "blr05\r\nsdfsdkfhsklfh";
        //System.out.println(s);
        Matcher matcher = Pattern.compile("^ak\\s*=\\s*(\\w+)", Pattern.MULTILINE)
                .matcher(s);
        matcher.find();
        // This one works
        System.out.println("first match " + matcher.group(1));
        // Below 2 lines throws IndexOutOfBoundsException
        System.out.println("second match " + matcher.group(2));
        System.out.println("third match " + matcher.group(3));

    }

Above code throws Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 2 Exception.

So My question is how Matcher.group() works and As you can see i'll have 3 matching string, how can i print all of them using the group().

like image 449
Amit Avatar asked Jan 04 '23 22:01

Amit


2 Answers

It is clear that you have only one group :

^ak\\s*=\\s*(\\w+)
//          ^----^----------this is the only group 

instead you have to use a loop for example :

while(matcher.find()){
    System.out.println("match " + matcher.group());
}

Outputs

match = foo
match = bar
match = blr05

read about groups:

Capturing group

Parentheses group the regex between them. They capture the text matched by the regex inside them into a numbered group that can be reused with a numbered backreference. They allow you to apply regex operators to the entire grouped regex.

like image 94
YCF_L Avatar answered Jan 19 '23 00:01

YCF_L


You seemed to be confused by capture groups and the number of matches found in your string with the given pattern. In the pattern you used, you only have one capture group:

^ak\\s*=\\s*(\\w+)

A capture group is marked using parentheses in the pattern.

If you want to retrieve every match of your pattern against the input string, then you should use a while loop:

while (matcher.find()) {
    System.out.println("entire pattern: " + matcher.group(0));
    System.out.println("first capture group: " + matcher.group(1));
}

Each call to Matcher#find() will apply the pattern against the input string, from start to end, and will make available whatever matches.

like image 35
Tim Biegeleisen Avatar answered Jan 18 '23 23:01

Tim Biegeleisen