developer033
developer033

Reputation: 24884

Get all captured groups in Java

I want to match a single word inside brackets(including the brackets), my Regex below is working but it's not returning me all groups.

Here's my code:

String text = "This_is_a_[sample]_text[notworking]";
Matcher matcher = Pattern.compile("\\[([a-zA-Z_]+)\\]").matcher(text);                                     
if (matcher.find()) {
    for (int i = 0; i <= matcher.groupCount(); i++) {
    System.out.println("------------------------------------");
    System.out.println("Group " + i + ": " + matcher.group(i));
}

Also I've tested it in Regex Planet and it seems to work.

It must return 4 groups:

------------------------------------
Group 0: [sample]
------------------------------------
Group 1: sample
------------------------------------
Group 2: [notworking]
------------------------------------
Group 3: notworking

But it's returning just it:

------------------------------------
Group 0: [sample]
------------------------------------
Group 1: sample

What's wrong?

Upvotes: 23

Views: 21838

Answers (4)

Alexandr Arhipov
Alexandr Arhipov

Reputation: 947

If you know the exact amount of matching groups, with java 9 or later it could be done like this:

    String text = "This_is_a_[sample]_text[notworking]";
    Pattern pattern = Pattern.compile("\\[(\\w*)\\]");
    List<Pair<String, String>> result = pattern.matcher(text).results()
            .map(matchResult -> Pair.of(matchResult.group(0), matchResult.group(1)))
            .toList();

enter image description here

Upvotes: 2

Artjom Prozorov
Artjom Prozorov

Reputation: 127

Also if you know the amount of matches you will get, you can find groups and add them to list then just take values from list when needed to assigned them somewhere else

 public static List<String> groupList(String text, Pattern pattern) {
    List<String> list = new ArrayList<>();
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        for (int i = 1; i <= matcher.groupCount(); i++) {
        list.add(matcher.group(i));
            }
        }
    return list;

Upvotes: 3

rock321987
rock321987

Reputation: 11032

JAVA does not offer fancy global option to find all the matches at once. So, you need while loop here

int i = 0;
while (matcher.find()) {
   for (int j = 0; j <= matcher.groupCount(); j++) {
      System.out.println("------------------------------------");
      System.out.println("Group " + i + ": " + matcher.group(j));
      i++;
   }
}

Ideone Demo

Upvotes: 26

mastov
mastov

Reputation: 2982

Groups aren't thought to find several matches. They are thought to identify several subparts in a single match, e.g. the expression "([A-Za-z]*):([A-Za-z]*)" would match a key-value pair and you could get the key as group 1 and the value as group 2.

There is only 1 group (= one brackets pair) in your expression and therefore only the groups 0 (always the whole matched expression, independently of your manually defined groups) and 1 (the single group you defined) are returned.

In your case, try calling find iteratively, if you want more matches.

int i = 0;
while (matcher.find()) {
    System.out.println("Match " + i + ": " + matcher.group(1));
    i++;
}

Upvotes: 10

Related Questions