JAVA中的CSV解析器,字符串中的双引号(SuperCSV,OpenCSV)

时间:2014-04-10 23:08:14

标签: java parsing csv quotes supercsv

整天我一直在寻找如何解决这个问题,什么都没有...... 我想写函数,它将CSV文件转换为列表(字符串)的集合。 这是这个功能:

public Collection<? extends List<String>> parse() throws IOException {
    Collection<List<String>> collectionOfLists = new ArrayList<List<String>>();
    CsvListReader parser = new CsvListReader(Files.newBufferedReader(pathToFile, StandardCharsets.UTF_8), CsvPreference.EXCEL_PREFERENCE);

    List<String> row;
    while( (row = parser.read()) != null)
        collectionOfLists.add(row);

    return collectionOfLists;
}

public static String toString(Collection<? extends List<String>> csv) {
    StringBuilder builder = new StringBuilder();
    for(List<String> l : csv) {
        for(String s : l)
            builder.append(s).append(',');
        if(builder.length() > 0)
            builder.setCharAt(builder.length()-1,'\n');
    }
    return builder.toString();
}

但是,例如对于那个输入:

id, name, city, age
1,"Bob",London,12

toString(parse())的输出是:

id, name, city, age
1,Bob,London,12 

而不是像输入一样:/我该怎么做,那个字符串包含\“(引号)? 请帮帮我。

3 个答案:

答案 0 :(得分:1)

在您提供的CsvPreference.EXCEL_PREFERENCE中,引号字符为",如javadoc中所述。引号字符是一个字符,用于包装希望按字面显示的特殊字符。

因此,对于这些偏好,生成CSV内容的适当方式是

id, name, city, age
1,"""Bob""",London,12

否则,CSV解析器只会想到

"Bob"

意味着,字面意思

Bob

因为引号之间没有其他特殊字符。但引用是一个特殊的字符,所以如果它出现在引号之间,它将被视为字面上的引用。

或者,提供一个具有不同引号字符的不同CsvPreference对象。

只有在您确定CSV制作人发送给您的内容后才能做出此决定。

答案 1 :(得分:1)

您可以创建自己的偏好。

CsvPreference excelPreference = new CsvPreference.Builder('\'', ',', "\n").build();
CsvListReader parser = new CsvListReader(Files.newBufferedReader(pathToFile , StandardCharsets.UTF_8), excelPreference);

之后,它将按预期输出。 在此示例中,如果您在csv文件中具有该引号,则将删除单引号,并保持双引号不变。

答案 2 :(得分:1)

从您的问题中不清楚您是否要求......

<强> 1。我的数据包含引号 - 为什么它们会被删除?

在这种情况下,我指向CSV specification,因为您的CSV文件未正确转义,因此这些报价实际上并不是您数据的一部分。

应该是

1,""Bob"",London,12

不是

1,"Bob",London,12

<强> 2。如何在撰写时应用引号(即使数据不包含逗号,引号等)?

默认情况下,Super CSV仅在必要时转义(该字段包含逗号,双引号或换行符)。

如果您确实要启用引号,则可以使用quote mode配置超级CSV。

例如,您始终可以使用以下首选项引用示例中的name列:

private static final CsvPreference ALWAYS_QUOTE_NAME_COL = 
    new CsvPreference.Builder(CsvPreference.STANDARD_PREFERENCE)
    .useQuoteMode(new ColumnQuoteMode(2)).build();

或者,如果您想引用所有内容,那么您可以使用AlwaysQuoteMode,或者如果您想要一个完全自定义的解决方案,那么您可以编写自己的QuoteMode