Java Split isst meine Charaktere

Ich habe eine Saite wie diese String str = "la$le\\$li$lo" .

Ich möchte es teilen, um die folgende Ausgabe zu erhalten: "la","le\\$li","lo" . Das $ ist ein $ maskiert, so dass es in der Ausgabe belassen werden sollte.

Aber wenn ich str.split("[^\\\\]\\$") mache, str.split("[^\\\\]\\$") ich "l","le\\$l","lo" .

Von was ich meine Regex bekomme ist ein $ und i $ und entfernen dann. Irgendeine Idee, wie ich meine Charaktere zurückbekomme?

Vielen Dank

Verwenden Sie keine Zusicherungen mit der Breite Null:

  String str = "la$le\\$li$lo"; System.out.println(java.util.Arrays.toString( str.split("(?< !\\\\)\\$") )); // prints "[la, le\$li, lo]" 

Die Regex ist im Wesentlichen

 (?< !\\)\$ 

Es verwendet negatives Lookbehind, um zu bestätigen, dass es kein vorangestelltes \ .

Siehe auch

  • regular-expressions.info/Lookarounds

Weitere Beispiele für das Aufteilen von Assertionen

Einfache Satzaufteilung, Satzzeichen beibehalten:

  String str = "Really?Wow!This.Is.Awesome!"; System.out.println(java.util.Arrays.toString( str.split("(?< =[.!?])") )); // prints "[Really?, Wow!, This., Is., Awesome!]" 

Teilen einer langen Zeichenfolge in Teile fester Länge mit \G

  String str = "012345678901234567890"; System.out.println(java.util.Arrays.toString( str.split("(?< =\\G.{4})") )); // prints "[0123, 4567, 8901, 2345, 6789, 0]" 

Verwenden einer Lookbehind- / Lookahead-Kombination:

  String str = "HelloThereHowAreYou"; System.out.println(java.util.Arrays.toString( str.split("(?< =[az])(?=[AZ])") )); // prints "[Hello, There, How, Are, You]" 

Verwandte Fragen

  • Können Sie in String-Split einen passwortlosen Regex mit Nullbreite verwenden?
  • Rückverweise in Lookbehind
  • Wie konvertiere ich CamelCase in menschenlesbare Namen in Java?

Der Grund dafür, dass a $ und i $ entfernt werden, ist, dass regexp [^\\]\$ mit jedem Zeichen übereinstimmt, das nicht ‘\’ gefolgt von ‘$’ ist. Sie müssen Assertionen mit der Breite null verwenden

Dies ist das gleiche Problem, das Leute versuchen, q zu finden, nicht gefolgt von dir.

Ein erster Schnitt in der richtigen Regexp ist /(?< !\\)\$/ ( "(?< !\\\\)\\$" in Java))

 class Test { public static void main(String[] args) { String regexp = "(?< !\\\\)\\$"; System.out.println( java.util.Arrays.toString( "1a$1e\\$li$lo".split(regexp) ) ); } } 

Erträge:
[1a, 1e\$li, lo]

Sie können zuerst versuchen, “\ $” durch eine andere Zeichenfolge zu ersetzen, z. B. die URL-Codierung für $ (“% 24”), und dann teilen:

 String splits[] = str.replace("\$","%24").split("[^\\\\]\\$"); for(String str : splits){ str = str.replace("%24","\$"); } 

Ganz allgemein, wenn str durch etwas wie konstruiert wird

 str = a + "$" + b + "$" + c 

Dann können Sie a, b und c URLEncodieren, bevor Sie sie zusammenfügen

 import java.net.URLEncoder.encode; ... str = encode(a) + "$" + encode(b) + "$" + encode(c) 
 import java.util.regex.*; public class Test { public static void main(String... args) { String str = "la$le\\$li$lo"; Pattern p = Pattern.compile("(.+?)([^\\\\]\\$)"); Matcher m = p.matcher(str); while (m.find()) { System.out.println(m.group(1)); System.out.println(m.group(2)); } } } 

gibt

 l a$ le\$l i$