Ява 6 регулярных выражений нескольких совпадений одной группы

Вот простой шаблон: [key]: [value1] [value2] [value3] [valueN]

Я хочу получить:

  • массив значений

Вот мое регулярное выражение: ^([^:]+):(:? ([^ ]+))++$

Вот мой текст: foo: a b c d

Matcher дает мне 2 группы: foo (как ключ) и d (как значения).

Если я использую +? вместо ++, я получаю a, а не d.

Итак, java возвращает мне первое (или последнее) появление группы.

Я не могу использовать find() здесь, потому что есть только один.

Что я могу сделать, кроме разделения регулярного выражения на 2 части и использования find для массива значений? Я работал с регулярными выражениями во многих других средах, и почти у всех из них есть возможность получать "первое появление группы 1", "второе появление группы 1" и т.д.

Как мне сделать с помощью java.util.regex в JDK6?

Спасибо.

Ответ 1

Общее количество совпадающих групп не зависит от целевой строки ("foo: a b c d", в вашем случае), но от шаблона. Ваша модель всегда будет иметь 3 группы:

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

Группа 1 st будет удерживать ваш ключ, а группа 2 nd которая совпадает с группой 3, но затем включает пробел, всегда будет содержать только 1 ваших значений. Это либо первые значения (в случае ungreedy +?), либо последнее значение (в случае жадного соответствия).

Что вы можете сделать, это просто совпадение:

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

чтобы вы имели следующие совпадения:

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

а затем разделите группу 2 nd на белые пробелы, чтобы получить все значения:

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));
    }
  }
}

который будет печатать:

key=foo, values=[a, b, c, d]

Ответ 2

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);

Он печатает:

key=foo, values=[a, b, c, d]