Question

J'utilise des expressions régulières pour essayer de faire correspondre les blocs de section dans un fichier INI. J'utilise la recette donnée dans le livre expressions régulières livre de recettes , mais il n'a pas semblent travailler pour moi.

Voici le code que je utilise:

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

Voici le contenu de mon fichier d'entrée:

[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

Le problème est que sectionBlock finit par être égale à tout le contenu du fichier, plutôt que la première section.

(je ne sais pas si ce qui compte, mais je fais cela sur Windows et les séparateurs de ligne dans s2 sont égaux à « \ r \ n » (au moins, c'est ce que le débogueur IDEA les affiche sous forme). )

Qu'est-ce que je fais mal ici?

Était-ce utile?

La solution

Essayer cette regex à la place:

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

ou la chaîne Java regex littérale:

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

A (courte) explication:

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

En clair, on lirait:

  

un match « [ » suivi par un ou plusieurs   caractères sauf '[', '\ r' et '\ n',   suivi d'un « ] » (appelons-ce   match de X). Ensuite, pour chaque chaîne vide   dans le texte, d'abord regarder vers l'avenir pour voir si   vous ne voyez pas un match X, si vous ne le faites pas,   puis correspond à tout caractère.

Autres conseils

Vous utilisez le * quantificateur gourmand correspondant à la plus longue chaîne possible. Utilisez le *? quantificateurs réticents au lieu d'obtenir le plus correspondance possible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top