Reading csv files when having double quotes in a value

Viewed 125

I'm trying to read a CSV file that uses semicolon (;) to separate the fields like this:

cars;countries;grades;color;speed

"car1;car2;car3;car4;car5;car6;car7;car8;car8";USA;26;green;230

As you guys can see, I have a lot of info in the same "box" separated with ; inside double quotes (""), but when I try to catch the info and store it inside an ArrayList with Java, I'm getting 2 errors: My class below:

public class ReadCsv {
    
    private ArrayList<IntelCorp > intelList= new ArrayList<>();

    public ArrayList<IntelCorp > ProcessCsv(String path){
        Path pathToFile = Paths.get(path);
            try(BufferedReader br = Files.newBufferedReader(pathToFile,StandardCharsets.ISO_8859_1)){
                String row = br.readLine();
                while(row!=null) {
                    String [] atributos = row.split(";");
                    IntelCorp intel = getIntel(atributos);
                    intelList.add(intel);
                    row = br.readLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        return intelList;
    }
    // i use de [] to get only the info that i need in the csv and not all of it

    private IntelCorp getIntel(String[] atributos) {
        String cars= atributos[0];
        String countries= atributos[1];
        String grades= atributos[2];
        String speed= atributos[4];

        IntelCorp intel = new IntelCorp (cars, countries, grades, speed);
        return intel;
    }

The problem is, the String [] atributos = row.split(";") ARE NOT respecting the double quotes (" ") and are using the inside semicolons to split, which is leading me to an ArrayIndexOutOfBoundException and messing up the info.

I tried to use regex like this: row.split(";(?=([^\"]|\"[^\"]*\")*$)") instead, but I'm getting ArrayIndexOutOfBoundsException when I run it, AND stackOverFlow error when I try to debug it, which are VERY confusing. I also tried to use some external library but I couldn't configure it to my needs. I'm dumb, I know. If you could do it I would appreciate. Some help?

1 Answers

You can try a pretty straightforward and hardcoded way to achieve this. Considering you will be getting your value always only in this format "car1;car2;car3;car4;car5;car6;car7;car8;car8";USA;26;green;230

Split the string into 2 parts. One will have the value of "cars" only and another one will contain the rest of the string. After that perform a split on the 2nd string.

String cars = row.substring(1, row.lastIndexOf("\""));
String withOutcars = row.substring(row.lastIndexOf("\"")+2,row.length());

//replace the ; in cars value if you want.
cars = cars.replace(";", " ");
String arr[] = withOutcars.split(";");

String atributos[] = new String[arr.length+1];
atributos[0] = cars;
for(int i =0 ;i <arr.length ; i++){
    atributos[i+1] =arr[i] ;
}
Related