Вы практически ответили на вопрос сами: сделайте их ленивыми.То есть используйте ленивые (иначе говоря, не жадные или неохотные ) квантификаторы.Просто измените каждый (\S+)
на (\S+?)
, а каждый (.*)
на (.*?)
.Но если бы это был я, я бы изменил эти подвыражения, чтобы они никогда не могли совпадать слишком сильно, независимо от жадности.Например, вы можете использовать ([^\s\[]+)
для имени класса, ([^\s=]+)
для ключа и "([^"]*)"
для значения.
Однако я не думаю, что это решит вашу реальную проблему.Как только вы получите его, чтобы он правильно соответствовал всем парам ключ / значение, вы обнаружите, что он только захватывает первую пару (группы № 2 и № 3) и последнюю пару (группы № 4).и № 5).Это потому, что каждый раз, когда (?:\s*,\s*(\S+)\s*=\s*"(.*)"\s*)*
повторяется, эти две группы перезаписывают свое содержимое, и все, что они записали на предыдущей итерации, теряется.Там не обойтись, это как минимум двухступенчатая операция.Например, вы можете сопоставить все пары ключ / значение как блок, а затем выделить отдельные пары.
Еще одна вещь.Эта строка:
if(matcher.groupCount() < 2){
... вероятно, не делает то, что вы думаете, что делает.groupCount()
- статическое свойство объекта Pattern;он говорит, сколько групп захвата в регулярном выражении.В случае успеха или неудачи совпадения, groupCount()
всегда будет возвращать одно и то же значение - в данном случае, пять.Если совпадение прошло успешно, некоторые из групп захвата могут быть нулевыми (что указывает на то, что они не участвовали в матче), но их всегда будет пять.
РЕДАКТИРОВАТЬ: Я подозреваю, что этото, что вы пытались изначально:
Pattern p = Pattern.compile(
"(?:([^\\s\\[]+)\\[|\\G)([^\\s=]+)=\"([^\"]*)\"[,\\s]*");
String s = "org.myobject[key1=\"value1\", key2=\"value2\", key3=\"value3\"]";
Matcher m = p.matcher(s);
while (m.find())
{
if (m.group(1) != null)
{
System.out.printf("class : %s%n", m.group(1));
}
System.out.printf("key : %s, value : %s%n", m.group(2), m.group(3));
}
вывод:
class : org.myobject
key : key1, value : value1
key : key2, value : value2
key : key3, value : value3
Ключом к пониманию регулярного выражения является эта часть: (?:([^\s\[]+)\[|\G)
.На первом проходе это соответствует имени класса и открывающей квадратной скобке.После этого \G
вступает во владение, привязывая следующий матч к позиции, где закончился предыдущий матч.