有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是否忽略Apache Commons CSV/OpenCSV中QuotenClosed字段中的分隔符?

我必须解析一个csv文件,该文件包含如下字段:

("FOO, BAR BAZ", 42)

并产生两个字段:

FOO, BAR BAZ  
42

我不知道如何使用ApacheCommonsCSV或OpenCSV简洁地做到这一点,所以我正在寻找一些指导。这可能只是因为我不完全理解org.apache.commons.csv.CSVFormat属性“quoteChar”which is touched on in the documentation,但从未在我能找到的任何地方清楚地解释过。如果是这样的话,如果你能告诉我如何更好地记录这个特性,那将是非常有帮助的

下面是一个简单的例子,展示了我的问题、我的尝试和结果:

        String test = "(\"FOO, BAR BAZ\", 42)";
        int numTries = 5;
        CSVParser[] tries = new CSVParser[numTries];
        tries[0] = CSVParser.parse(line, CSVFormat.DEFAULT.withRecordSeparator("\n"));//BAR BAZ"
        tries[1] = CSVParser.parse(line, CSVFormat.DEFAULT.withQuote('"'));//BAR BAZ"
        tries[2] = CSVParser.parse(line, CSVFormat.DEFAULT.withQuote(null));//BAR BAZ"
        tries[3] = CSVParser.parse(line, CSVFormat.DEFAULT.withQuote('"').withQuoteMode(QuoteMode.NON_NUMERIC));//BAR BAZ"
        tries[4] = CSVParser.parse(line, CSVFormat.DEFAULT.withRecordSeparator(")\n("));//BAR BAZ"

        for(int i = 0; i < numTries; i++){
            CSVRecord record = tries[i].getRecords().get(0);
            System.out.println(record.get(1));//.equals("42"));
        }  

请注意,如果从输入中排除括号,则效果良好


共 (3) 个答案

  1. # 1 楼答案

    您可以通过opencsv实现这一点,如下所示:

    import com.opencsv.CSVReader;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class NewClass1 {
        public static void main(String[] args) throws IOException {
            String fileName = "C:\\yourFile.csv";
            String [] nextLine;
            // use the three arg constructor to tell the reader which delimiter you have in your file(2nd arg : here ',')                                                          
            // you can change this to '\t' if you have tab separeted file or ';' or ':' ... whatever your delimiter is
            // (3rd arg) '"' if your fields are double quoted or '\'' if single quoted or no 3rd arg if the fields are not quoted
            CSVReader reader = new CSVReader(new FileReader(fileName), ',' ,'"');
            // nextLine[] is an array of values from the line
            // each line represented by String[], and each field as an element of the array
            while ((nextLine = reader.readNext()) != null) {        
                System.out.println("nextLine[0]: " +nextLine[0]);
                System.out.println("nextLine[1]: " +nextLine[1]);
            }
        }
    }
    
  2. # 2 楼答案

    您可以使用OpenCSVCSVReader读取数据并获取数据元素,如下所示:

    public static void main(String[] args) {
        try(FileReader fr = new FileReader(new File("C:\\Sample.txt"));
                    CSVReader csvReader = new CSVReader(fr);) {
                String[] data = csvReader.readNext();
                for(String data1 : data) {
                    System.out.println(data1);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
  3. # 3 楼答案

    对我来说,commons csv的默认格式对于格式正确的csv消息来说是正确的:

        Reader in = new StringReader("\"FOO, BAR BAZ\", 42");
        Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
        for (CSVRecord record : records) {
            for(int i = 0;i < record.size();i++) {
                System.out.println("At " + i + ": " + record.get(i));
            }
        }
    

    导致:

    At 0: FOO, BAR BAZ
    At 1:  42
    

    对于特殊格式的行,您可能需要做更多的处理,删除这些括号:

        BufferedReader lineReader = new BufferedReader(
                new StringReader("(\"FOO, BAR BAZ\", 42)\n(\"FOO, BAR FOO\", 44)"));
    
        while(true) {
            String line = lineReader.readLine();
            if (line == null) {
                break;
            }
    
            String adjustedLine = line.substring(1, line.length() - 1);
            records = CSVFormat.DEFAULT.parse(new StringReader(adjustedLine));
            for (CSVRecord record : records) {
                for (int i = 0; i < record.size(); i++) {
                    System.out.println("At " + i + ": " + record.get(i));
                }
            }
        }