L'approccio più semplice non è quello di abbinare i delimitatori, cioè le virgole, con una logica aggiuntiva complessa per abbinare ciò che è effettivamente inteso (i dati che potrebbero essere citati stringhe), solo per escludere falsi delimitatori, ma piuttosto abbinare i dati previsti in primo luogo.
Il modello è composto da due alternative, una stringa tra virgolette ( "[^"]*"
o ".*?"
) o tutto fino alla virgola successiva ( [^,]+
). Per supportare celle vuote, dobbiamo consentire che l'elemento non quotato sia vuoto e consumare la virgola successiva, se presente, e utilizzare l' \\G
ancoraggio:
Pattern p = Pattern.compile("\\G\"(.*?)\",?|([^,]*),?");
Il modello contiene anche due gruppi di acquisizione per ottenere il contenuto della stringa tra virgolette o il contenuto normale.
Quindi, con Java 9, possiamo ottenere un array come
String[] a = p.matcher(input).results()
.map(m -> m.group(m.start(1)<0? 2: 1))
.toArray(String[]::new);
mentre le versioni precedenti di Java richiedono un ciclo simile
for(Matcher m = p.matcher(input); m.find(); ) {
String token = m.group(m.start(1)<0? 2: 1);
System.out.println("found: "+token);
}
Aggiunta degli elementi a List
o una matrice viene lasciata come accisa al lettore.
Per Java 8, è possibile utilizzare l' results()
implementazione di questa risposta , per farlo come la soluzione Java 9.
Per contenuti misti con stringhe incorporate, come nella domanda, puoi semplicemente usare
Pattern p = Pattern.compile("\\G((\"(.*?)\"|[^,])*),?");
Ma poi, le stringhe vengono mantenute nella loro forma quotata.
String line = "equals: =,\"quote: \"\"\",\"comma: ,\""
tutto ciò che devi fare è togliere la doppia citazione estranea personaggi.