L'approche la plus simple n'est pas de faire correspondre les délimiteurs, c'est-à-dire les virgules, avec une logique supplémentaire complexe pour faire correspondre ce qui est réellement prévu (les données qui pourraient être des chaînes de caractères), juste pour exclure les faux délimiteurs, mais plutôt faire correspondre les données prévues en premier lieu.
Le modèle se compose de deux alternatives, une chaîne entre guillemets ( "[^"]*"
ou ".*?"
) ou tout jusqu'à la prochaine virgule ( [^,]+
). Pour prendre en charge les cellules vides, nous devons autoriser l'élément non cité à être vide et consommer la virgule suivante, le cas échéant, et utiliser l' \\G
ancre:
Pattern p = Pattern.compile("\\G\"(.*?)\",?|([^,]*),?");
Le modèle contient également deux groupes de capture pour obtenir soit le contenu de la chaîne citée, soit le contenu brut.
Ensuite, avec Java 9, nous pouvons obtenir un tableau comme
String[] a = p.matcher(input).results()
.map(m -> m.group(m.start(1)<0? 2: 1))
.toArray(String[]::new);
alors que les anciennes versions de Java ont besoin d'une boucle comme
for(Matcher m = p.matcher(input); m.find(); ) {
String token = m.group(m.start(1)<0? 2: 1);
System.out.println("found: "+token);
}
L'ajout des éléments à un List
ou à un tableau est laissé comme accise au lecteur.
Pour Java 8, vous pouvez utiliser l' results()
implémentation de cette réponse , pour le faire comme la solution Java 9.
Pour un contenu mixte avec des chaînes intégrées, comme dans la question, vous pouvez simplement utiliser
Pattern p = Pattern.compile("\\G((\"(.*?)\"|[^,])*),?");
Mais ensuite, les chaînes sont conservées dans leur forme entre guillemets.
String line = "equals: =,\"quote: \"\"\",\"comma: ,\""
, tout ce que vous avez à faire est de supprimer le guillemet double superflu personnages.