【问题标题】:CSV parser in JAVA, double quotes in string (SuperCSV, OpenCSV)JAVA中的CSV解析器,字符串中的双引号(SuperCSV,OpenCSV)
【发布时间】:2014-04-10 23:08:13
【问题描述】:

我整天都在寻找如何解决这个问题,但什么也没有…… 我想编写函数,将 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 

而不是相同的输入:/ 我能做什么,字符串包含 \" (引号)? 请帮帮我。

【问题讨论】:

  • errr...如果您想自己编写,为什么问题标题中的“SuperCSV,OpenCSV”?
  • 似乎库剥离了""
  • 因为我尝试使用这些类,但没有找到任何解决方案
  • javadoc 可能有你想要的。
  • 我看了好几遍...

标签: java parsing csv quotes supercsv


【解决方案1】:

从你的问题中不清楚你是否在问......

1.我的数据包含引号 - 为什么要去掉它们?

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

应该是

1,""Bob"",London,12

不是

1,"Bob",London,12

2。写作时如何应用引号(即使数据不包含逗号、引号等)?

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

如果您真的想启用引号,那么您可以使用quote mode 配置 Super CSV。

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

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

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

【讨论】:

  • 好的,谢谢。是否有任何解决方案可以使解析器在原处留下引号,如果输入中没有引号,则打印不带引号的字符串?在某种意义上,例如,, --&gt; ,null, (or ,,), "Bob" --&gt; "Bob", Bob --&gt; Bob and "" --&gt; "" 在 SuperCSV 或 OpenCSV 的帮助下这可能吗?
  • 读者有一个getUntokenizedRow() 方法,但这并不是你真正想要的。我怀疑许多库会以相同的输入/输出再次从 CSV 转换为 Java 到 CSV(数据将相同,但包含的结构可能不同)。
【解决方案2】:

您可以创建自己的偏好。

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

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

【讨论】:

    【解决方案3】:

    在您给出的CsvPreference.EXCEL_PREFERENCE 中,引号字符是",如javadoc 中所述。引号字符是您用来包装希望按字面显示的特殊字符的字符。

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

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

    否则,CSV 解析器只会认为

    "Bob"
    

    意思是,字面意思,

    Bob
    

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

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

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

    【讨论】:

    • 好的,我知道了。我的意思是如何将 CSV 文件转换为保留引号的列表集合。如果您提供不同的 CsvPreference 例如new CsvPreference.Builder('\'', ',', "\n").build() 比,它不起作用:id,text 1,"它不起作用,伙计"
    • @user3521479 javadoc 展示了如何做到这一点。 sendon1982 也提供了一个示例。
    猜你喜欢
    • 2020-03-07
    • 2016-04-15
    • 2012-01-07
    • 1970-01-01
    • 2020-03-17
    • 2021-10-24
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    相关资源
    最近更新 更多