0

正規表現を使用して、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 デバッガーはそのように表示します)。)

ここで何が間違っていますか?

4

2 に答える 2

5

代わりに次の正規表現を試してください。

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

または Java 文字列リテラル正規表現:

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

(短い)説明:

(?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' を除く 1 つ以上の文字が続き、その後に ']' が続くものに一致します (これを X と呼びましょう)。次に、テキスト内のすべての空の文字列について、最初に一致する X が表示されないかどうかを確認し、表示されない場合は任意の文字に一致します。

于 2009-10-13T17:47:15.360 に答える
0

*可能な限り長い文字列に一致する貪欲な量指定子を使用します。*?可能な限り最短の一致を取得するには、代わりに消極的な量指定子を使用してください。

于 2009-10-13T16:59:37.180 に答える