Frage

Ich bin mit regulären Ausdrücken versuchen Abschnitt Blöcke in einer INI-Datei übereinstimmen. Ich bin mit dem Rezept in dem Buch Reguläre Ausdrücke Kochbuch , aber es funktioniert nicht scheint für mich zu arbeiten.

Hier ist der Code, den ich mit:

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();
}

Hier sind die Inhalte meiner Eingabedatei:

[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

Das Problem ist, dass sectionBlock Ende bis zu dem gesamten Inhalt der Datei gleich ist, und nicht nur der erste Abschnitt.

(Ich weiß nicht, ob es wichtig ist, aber ich mache das auf Windows und die Zeilenseparatoren in s2 gleich „\ r \ n“ (zumindest das ist, was die Idee Debugger zeigt sie als). )

Was mache ich hier falsch?

War es hilfreich?

Lösung

Versuchen Sie, diese Regex statt:

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

oder die Java Stringliteral regex:

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

A (kurz) Erklärung:

(?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

Im Klartext würde es lesen, wie:

  

Match a '[', gefolgt von einem oder mehreren   Zeichen außer '[', '\ r' und '\ n',   gefolgt von einem ‚]‘ (wir nennen dies   Match X). Dann gilt für jeden leeren String   im Text, zunächst einen Blick voraus zu sehen, ob   Sie kein Spiel X sehen, wenn Sie es nicht tun,   dann jedes Zeichen.

Andere Tipps

Sie verwenden, um die gierigen Quantor * die längste mögliche String-Matching. Verwenden Sie das nur ungern quantifier *? stattdessen die kürzeste mögliche Übereinstimmung zu erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top