RegEx для чтения нескольких параметров неизвестной кратности - PullRequest
5 голосов
/ 26 мая 2011

Я немного застрял в регулярном выражении. Рассмотрим следующий код:

    String regFlagMulti = "^(\\[([\\w=]*?)\\])*?$";
    String flagMulti = "[TestFlag=1000][TestFlagSecond=1000]";
    Matcher mFlagMulti = Pattern.compile(regFlagMulti).matcher(flagMulti);

    if(mFlagMulti.matches()){
        for(int i = 0; i <= mFlagMulti.groupCount(); i++){
            System.out.println(mFlagMulti.group(i));
        }
    }else{
        System.out.println("MultiFlag didn't match!");
    }

Мне нужен обычный шаблон, который дает мне текст внутри [] ; каждый в группе полученного объекта Matcher.

Важно: я не знаю, сколько [] выражений находится внутри входной строки!

Для приведенного выше кода он выводит:

[TestFlag=1000][TestFlagSecond=1000]
[TestFlagSecond=1000]
TestFlagSecond=1000

Я не могу заставить работать обычный шаблон. У кого-нибудь есть идея?

Ответы [ 4 ]

3 голосов
/ 26 мая 2011

То, что я хочу, это обычный шаблон, который дает мне текст внутри [];каждый в группе полученного объекта Matcher.

К сожалению, этого нельзя сделать с помощью механизма регулярных выражений Java.Смотрите мой (аналогичный) вопрос здесь:


Эта группа:

(\\[([\\w=]*?)\\])*
\________________/

является группой № 1 и всегда будет содержать последнее совпадение для этой группы.


Вот предложение для решения, которое также выбирает ключ / значения:

String regFlagMulti = "(\\[(\\w*?)=(.*?)\\])";
String flagMulti = "[TestFlag=1000][TestFlagSecond=1000]";
Matcher mFlagMulti = Pattern.compile(regFlagMulti).matcher(flagMulti);

while (mFlagMulti.find()) {
    System.out.println("String: " + mFlagMulti.group(1));
    System.out.println("   key: " + mFlagMulti.group(2));
    System.out.println("   val: " + mFlagMulti.group(3));
    System.out.println();
}

Вывод:

String: [TestFlag=1000]
   key: TestFlag
   val: 1000

String: [TestFlagSecond=1000]
   key: TestFlagSecond
   val: 1000
3 голосов
/ 26 мая 2011

Вы можете попробовать следующее:

String regFlagMulti = "\\[(\\w+=.*?)\\]";
String flagMulti = "[TestFlag=1000][TestFlagSecond=1000]";
Matcher mFlagMulti = Pattern.compile(regFlagMulti).matcher(flagMulti);
while(mFlagMulti.find()){
    System.out.println(mFlagMulti.group(1));
}

Выход:

TestFlag=1000
TestFlagSecond=1000
3 голосов
/ 26 мая 2011

Используйте шаблон, который соответствует одному элементу в строке, и используйте Matcher.find() для перебора всей строки.

0 голосов
/ 26 мая 2011

Как правильно указал Аарон, используйте одну группу (они статичны для шаблона, повторы не добавляются в качестве дополнительных групп) и вызовите find.

Шаблон для использования может выглядеть следующим образом: \G\[([^\]]*)\](?=\[|$)

Группа 1 будет содержать текст внутри [].

Примечания:

\G продолжает совпадение, где последнийокончание матча

(?= является положительным прогнозом, позволяющим убедиться, что конец шаблона соответствует ожидаемому (например, либо конец строки, либо следующий [).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...