Сопоставить блоки секции INI - PullRequest
0 голосов
/ 13 октября 2009

Я использую регулярные выражения, чтобы попытаться сопоставить блоки раздела в файле INI. Я использую рецепт, приведенный в книге Поваренная книга регулярных выражений , но она мне не подходит.

Вот код, который я использую:

final BufferedReader in = new BufferedReader(
    new FileReader(file));
String s;
String s2 = "";
while((s = in.readLine())!= null)
    s2 += s + System.getProperty("line.separator");
in.close();

final String regex = "^\\[[^\\]\r\n]+](?:\r?\n(?:[^\r\n].*)?)*";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
String sectionBlock = null;
final Matcher regexMatcher = pattern.matcher(s2);
if (regexMatcher.find()) {
    sectionBlock = regexMatcher.group();
}

Вот содержимое моего входного файла:

[Section 2]
Key 2.0=Value 2.0
Key 2.2=Value 2.2
Key 2.1=Value 2.1

[Section 1]
Key 1.1=Value 1.1
Key 1.0=Value 1.0
Key 1.2=Value 1.2

[Section 0]
Key 0.1=Value 0.1
Key 0.2=Value 0.2
Key 0.0=Value 0.0

Проблема в том, что sectionBlock в конечном итоге равен всему содержимому файла, а не только первому разделу.

(Я не знаю, имеет ли это значение, но я делаю это в Windows, а разделители строк в s2 равны "\ r \ n" (по крайней мере, именно так отладчик IDEA отображает их как ).)

Что я здесь не так делаю?

Ответы [ 2 ]

5 голосов
/ 13 октября 2009

Попробуйте использовать это регулярное выражение:

(?ms)^\[[^]\r\n]+](?:(?!^\[[^]\r\n]+]).)*

или регулярное выражение Java String:

"(?ms)^\\[[^]\r\n]+](?:(?!^\\[[^]\r\n]+]).)*"

A (короткое) объяснение:

(?ms)          // enable multi-line and dot-all matching
^              // the start of a line
\[             // match a '['
[^]\r\n]+      // match any character except '[', '\r' and '\n', one or more times
]              // match a ']'
(?:            // open non-capturing group 1
  (?!          //   start negative look-ahead
    ^          //     the start of a line
    \[         //     match a '['
    [^]\r\n]+  //     match any character except '[', '\r' and '\n', one or more times
    ]          //     match a ']'
  )            //   stop negative look-ahead
  .            //   any character (including line terminators)
)*             // close non-capturing group 1 and match it zero or more times

На простом английском языке это звучит так:

Соответствует '[', за которым следует один или несколько символы кроме '[', '\ r' и '\ n', сопровождаемый ']' (давайте назовем это соответствует X). Тогда для каждой пустой строки в тексте сначала посмотрите вперед, чтобы увидеть, если вы не видите совпадения X, если вы этого не сделаете, затем сопоставьте любой символ.

0 голосов
/ 13 октября 2009

Вы используете жадный квантификатор *, соответствующий самой длинной строке. Вместо этого используйте квантификатор с неохотой *?, чтобы получить максимально короткое соответствие

...