S'il y a un élément avec une virgule dans le fichier CSV, le fractionner avec la méthode String.split normale résoudra le problème du fractionnement au milieu de l'élément.
Par exemple, s'il existe un tel enregistrement CSV
test.csv
ABC,DEF,GHI,'1,000,000',JKL,MN
Lorsque vous souhaitez fractionner cet enregistrement par des virgules, supposons que vous souhaitiez fractionner cette chaîne entre guillemets simples en une seule chaîne sans les séparer par des virgules.
Le résultat attendu à ce moment est
Résultats attendus
ABC
DEF
GHI
'1,000,000'
JKL
MN
Cependant, si vous utilisez la méthode de fractionnement normalement, elle sera divisée comme ceci.
split(",")Résultat décevant de
ABC
DEF
GHI
'1
000
000'
JKL
MN
J'ai essayé de découvrir ce qui s'est passé, comme les expressions régulières, mais en premier lieu, la méthode de fractionnement
"Fractionner lorsque les conditions sont remplies" Est une méthode
"Ne pas fractionner lorsque les conditions sont réunies" Je ne peux pas dire que (dans ce cas, la condition est "une virgule entre guillemets", et je ne peux pas dire qu'elle ne se divise pas seulement lorsque cette condition est remplie), j'ai donc abandonné et créé ma propre méthode.
Main.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
try {
String fileName= "C:\\temp\\test.csv"; //Fichier CSV que vous souhaitez lire
//Lire le fichier CSV d'entrée
File file= new File(fileName);
FileInputStream input = new FileInputStream(file);
InputStreamReader stream= new InputStreamReader(input,"SJIS");
BufferedReader br = new BufferedReader(stream);
String line = br.readLine();
//Appelez votre propre méthode
List<String> data = csvSplit(line);
for (String col : data) {
System.out.print(col + "\r\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static List<String> csvSplit(String line) {
char c;
StringBuilder s = new StringBuilder();
List<String> data = new ArrayList<String>();
boolean singleQuoteFlg = false;
for(int i=0; i < line.length(); i++){
c = line.charAt(i);
if (c == ',' && !singleQuoteFlg) {
data.add(s.toString());
s.delete(0,s.length());
} else if (c == ',' && singleQuoteFlg) {
s.append(c);
} else if (c == '\'') {
singleQuoteFlg = !singleQuoteFlg;
s.append(c);
} else {
s.append(c);
}
}
return data;
}
}
Voici les résultats de l'exécution.
Résultat d'exécution
ABC
DEF
GHI
'1,000,000'
JKL
Les virgules entre guillemets ne sont pas séparées et sont correctement considérées comme une seule chaîne.
Que fais tu
--Lire un enregistrement CSV (String line = br.readLine ();)
L'explication de la logique est comme ça. En passant, si vous ne souhaitez pas inclure de guillemets simples dans la sortie, ils ne seront pas inclus dans la sortie à moins que vous ne concaténiez avec StringBuilder.
Après modification csvSplit
private static List<String> csvSplit(String line) {
char c;
StringBuilder s = new StringBuilder();
List<String> data = new ArrayList<String>();
boolean singleQuoteFlg = false;
for(int i=0; i < line.length(); i++){
c = line.charAt(i);
if (c == ',' && !singleQuoteFlg) {
data.add(s.toString());
s.delete(0,s.length());
} else if (c == ',' && singleQuoteFlg) {
s.append(c);
} else if (c == '\'') {
singleQuoteFlg = !singleQuoteFlg;
// s.append(c); //Si vous arrêtez de connecter des caractères, les guillemets simples ne seront pas affichés!
} else {
s.append(c);
}
}
return data;
}
Résultat de l'exécution (sans guillemet simple)
ABC
DEF
GHI
1,000,000
JKL
Je me sens comme cela.
S'il y a un autre bon moyen, je vous serais reconnaissant si vous pouviez m'apprendre!