Java split está comendo meus personagens

Eu tenho uma string como esta String str = "la$le\\$li$lo" .

Eu quero dividi-lo para obter o seguinte resultado "la","le\\$li","lo" . O \ $ é um $ escaped por isso deve ser deixado na saída.

Mas quando eu faço str.split("[^\\\\]\\$") y obter "l","le\\$l","lo" .

Do que eu recebo o meu regex está combinando um $ e $ i e removendo então. Alguma ideia de como recuperar meus personagens?

obrigado

Use asserções de correspondência de largura zero:

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

O regex é essencialmente

 (?< !\\)\$ 

Usa lookbehind negativo para afirmar que não há um precedente \ .

Veja também

  • regular-expressions.info/Lookarounds

Mais exemplos de divisão em asserções

Divisão simples de frases, mantendo os sinais de pontuação:

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

Dividindo uma longa seqüência em partes de comprimento fixo, usando \G

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

Usando um combo lookbehind / lookahead:

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

Perguntas relacionadas

  • Você pode usar a regex de correspondência de largura zero na divisão de string?
  • Backreferences em lookbehind
  • Como faço para converter o CamelCase em nomes legíveis por humanos em Java?

O motivo pelo qual $ e i $ estão sendo removidos é que o regexp [^\\]\$ corresponde a qualquer caractere que não seja ‘\’ seguido por ‘$’. Você precisa usar afirmações de largura zero

Este é o mesmo problema que as pessoas tentam encontrar q não seguido por u.

Um primeiro corte no regexp adequado é /(?< !\\)\$/ ( "(?< !\\\\)\\$" em java)

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

Rendimentos:
[1a, 1e\$li, lo]

Você pode tentar primeiro replace “\ $” por outra string, como a URL Encoding por $ (“% 24”) e, em seguida, dividir:

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

Mais geralmente, se str é construído por algo como

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

Então você pode URLEncode a, bec antes de anexá-los juntos

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

 l a$ le\$l i$