A abordagem mais simples é não combinar delimitadores, ou seja, vírgulas, com uma lógica adicional complexa para corresponder ao que realmente é pretendido (os dados que podem ser citados), apenas para excluir delimitadores falsos, mas, em primeiro lugar, corresponder aos dados pretendidos.
O padrão consiste em duas alternativas, uma string entre aspas ( "[^"]*"
ou ".*?"
) ou tudo até a próxima vírgula ( [^,]+
). Para suportar células vazias, precisamos permitir que o item não citado fique vazio e consumir a próxima vírgula, se houver, e usar a \\G
âncora:
Pattern p = Pattern.compile("\\G\"(.*?)\",?|([^,]*),?");
O padrão também contém dois grupos de captura para obter o conteúdo da sequência de caracteres citada ou o conteúdo simples.
Em seguida, com o Java 9, podemos obter uma matriz como
String[] a = p.matcher(input).results()
.map(m -> m.group(m.start(1)<0? 2: 1))
.toArray(String[]::new);
enquanto as versões Java mais antigas precisam de um loop como
for(Matcher m = p.matcher(input); m.find(); ) {
String token = m.group(m.start(1)<0? 2: 1);
System.out.println("found: "+token);
}
A adição dos itens a uma List
ou a uma matriz é deixada como um imposto especial de consumo para o leitor.
No Java 8, você pode usar a results()
implementação desta resposta , para fazê-lo como a solução Java 9.
Para conteúdo misto com sequências incorporadas, como na pergunta, você pode simplesmente usar
Pattern p = Pattern.compile("\\G((\"(.*?)\"|[^,])*),?");
Mas então, as cadeias são mantidas em sua forma citada.
String line = "equals: =,\"quote: \"\"\",\"comma: ,\""
tudo o que você precisa fazer é retirar as aspas duplas estranhas personagens.