Da Java variabler Länge Look-behinds unterstützt (solange sie endlich sind), können Sie es tun, wie folgt tun:
import java.util.regex.*;
public class RegexTest {
public static void main(String[] argv) {
Pattern p = Pattern.compile("(?<=(?<!\\\\)(?:\\\\\\\\){0,10}):");
String text = "foo:bar\\:baz\\\\:qux\\\\\\:quux\\\\\\\\:corge";
String[] parts = p.split(text);
System.out.printf("Input string: %s\n", text);
for (int i = 0; i < parts.length; i++) {
System.out.printf("Part %d: %s\n", i+1, parts[i]);
}
}
}
(?<=(?<!\\)(?:\\\\){0,10})
für ein hinter aussieht gerade Anzahl von Backslashes (einschließlich Null, bis zu einem Maximum von 10).
Ausgang:
Input string: foo:bar\:baz\\:qux\\\:quux\\\\:corge
Part 1: foo
Part 2: bar\:baz\\
Part 3: qux\\\:quux\\\\
Part 4: corge
Eine andere Möglichkeit wäre es, die Teile selbst anzupassen, statt Spaltung an den Begrenzer.
Die seltsame Syntax ergibt sich daraus, dass es den Fall von leeren Stücken am Anfang und Ende der Zeichenfolge behandeln muss. Wenn eine Übereinstimmung genau null Zeichen umfasst, beginnt der nächste Versuch ein Zeichen nach dem Ende davon. Wenn nicht, würde es zu einer anderen leeren Zeichenfolge passen, und eine andere, ad infinitum & hellip;
(?<=\A|\G:)
wird entweder für den Start des Strings Blick hinter (das erste Stück) oder das Ende des vorherigen Spiels, durch den Separator, gefolgt. Wenn wir (?:\A|\G:)
hätten, würde es fehlschlagen, wenn das erste Stück leer ist (die Eingabe beginnt mit einem Trennzeichen).
\\.
passt auf alle maskierten Zeichen.
[^:\\]
passt auf ein beliebiges Zeichen, das nicht in einer Escape-Sequenz enthalten ist (weil \\.
beides verbraucht hat).
((?:\\.|[^:\\])*)
erfasst alle Zeichen bis zum ersten Nicht-Escape-Begrenzer in Fanggruppe 1.
Siehe auch http://stackoverflow.com/questions/820172/how-to-split-a-comma-separated-string-while-ignoring-escaped-commas. –