Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 6 regex multiple matches of one group

Tags:

java

regex

Here is simple pattern: [key]: [value1] [value2] [value3] [valueN]

I want to get:

  1. key
  2. array of values

Here is my regex: ^([^:]+):(:? ([^ ]+))++$

Here is my text: foo: a b c d

Matcher gives me 2 groups: foo (as key) and d (as values).

If I use +? instead of ++ I get a, not d.

So java returns me first (or last) occurrence of group.

I can't use find() here becase there is only one match.

What can I do except splitting regex into 2 parts and using find for the array of values? I have worked with regular expressions in many other environments and almost all of them have ability to fetch "first occurrence of group 1", "second occurrence of group 1" and so on.

How can I do with with java.util.regex in JDK6 ?

Thanks.

like image 746
Ilya.K Avatar asked Aug 27 '11 14:08

Ilya.K


2 Answers

The total number of match groups does not depend on the target string ("foo: a b c d", in your case), but on the pattern. Your pattern will always have 3 groups:

^([^:]+):(:? ([^ ]+))++$
 ^       ^   ^
 |       |   |
 1       2   3

The 1st group will hold your key, and the 2nd group, which matches the same as group 3 but then includes a white space, will always hold just 1 of your values. This is either the first values (in case of the ungreedy +?) or the last value (in case of greedy matching).

What you could do is just match:

^([^:]+):\s*(.*)$

so that you have the following matches:

- group(1) = "foo"
- group(2) = "a b c d"

and then split the 2nd group on it's white spaces to get all values:

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
  public static void main (String[] args) throws Exception {
    Matcher m = Pattern.compile("^([^:]+):\\s*(.*)$").matcher("foo: a b c d");
    if(m.find()) {
      String key = m.group(1);
      String[] values = m.group(2).split("\\s+");
      System.out.printf("key=%s, values=%s", key, Arrays.toString(values));
    }
  }
}

which will print:

key=foo, values=[a, b, c, d]
like image 105
Bart Kiers Avatar answered Nov 11 '22 19:11

Bart Kiers


Scanner s = new Scanner(input).useDelimiter(Pattern.compile(":?\\s+"));
String key = s.next();
ArrayList values = new ArrayList();
while (s.hasNext()) {
    values.add(s.next());
}
System.out.printf("key=%s, values=%s", key, values);

It prints:

key=foo, values=[a, b, c, d]
like image 34
opiethehokie Avatar answered Nov 11 '22 20:11

opiethehokie