Java 6 регулярное выражение нескольких совпадений одной группы - PullRequest
11 голосов
/ 27 августа 2011

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

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

  1. ключ
  2. массив значений

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

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

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

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

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

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

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

Как я могу сделать с java.util.regex в JDK6?

Спасибо.

Ответы [ 2 ]

9 голосов
/ 27 августа 2011

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

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

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

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

^([^:]+):\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 голосов
/ 18 октября 2013
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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...