Partidos INI bloqueo de los tramos
Pregunta
Estoy usando expresiones regulares para tratar de coincidir con bloques de sección en un archivo INI. Estoy usando la receta dada en el libro expresiones regulares Cookbook , pero no lo hace parece estar funcionando para mí.
Aquí está el código que estoy usando:
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();
}
A continuación los contenidos de mi archivo de entrada:
[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
El problema es que sectionBlock
termina siendo igual a todo el contenido del archivo, en lugar de sólo la primera sección.
(No sé si importa, pero estoy haciendo esto en Windows y los separadores de línea en s2
son iguales a "\ r \ n" (al menos, eso es lo que el depurador IDEA como los muestra). )
¿Qué estoy haciendo mal aquí?
Solución
Probar expresión regular en su lugar:
(?ms)^\[[^]\r\n]+](?:(?!^\[[^]\r\n]+]).)*
o la expresión regular literal String de Java:
"(?ms)^\\[[^]\r\n]+](?:(?!^\\[[^]\r\n]+]).)*"
A (corto) explicació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
En la llanura Inglés se leería como:
Partido un '[' seguido por uno o más los caracteres excepto '[', '\ r' y '\ n', seguido de un ']' (vamos a llamar a esta partido X). A continuación, para cada cadena vacía en el texto, primero mirar hacia adelante para ver si no ve un partido de X, si no lo hace, a continuación, coincide con cualquier carácter.
Otros consejos
Se utiliza el cuantificador *
codiciosos coincidente con la cadena más larga posible. Utilizar el cuantificador *?
reacios lugar para conseguir la coincidencia más corta posible.