解析CSV文件,但除了分隔数据外没有格式化

时间:2017-08-31 15:28:13

标签: java csv univocity

我有以下格式的数据

PAL : PAL : NF : "INCOME"."Taxable"
PAL : PAL : NF : "EXPENSES"."TotalExpenses"
PAL : PAL : NF : "EXPENSES"."Exceptional"

在java中,我只想分隔数据而不进行任何格式化,在输出中也应该引用。当使用以下代码时,我通常使用Univocity,

    //Simple CSV File Read
    List<String[]> allRows;
    try {
        CsvParserSettings settings = new CsvParserSettings();
        settings.getFormat().setLineSeparator("\n");
        settings.getFormat().setDelimiter(':');

        CsvParser parser = new CsvParser(settings);
        allRows = parser.parseAll(new FileReader(new File(csvFile)));
        int i =0, cols=0;
        for(String[] str:allRows){
            i++;
            cols = str.length;

            for(String s:str)
                System.out.print(s+" == ");

            System.out.println("");
            if(i == 10) break;
        }       
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }    

输出如下,期间符号在引号内,我期望输出像输入,引号应该来。

PAL == PAL == NF == INCOME"."Taxable
PAL == PAL == NF == EXPENSES"."TotalExpenses
PAL == PAL == NF == EXPENSES"."Exceptional

预期产出

PAL == PAL == NF == "INCOME"."Taxable"
PAL == PAL == NF == "EXPENSES"."TotalExpenses"
PAL == PAL == NF == "EXPENSES"."Exceptional"

3 个答案:

答案 0 :(得分:1)

图书馆的作者在这里。问题在于,"INCOME"."Taxable"作为引用值处理,它将INCOMETaxable之间的引号视为未转义的引号。

它基本上会尝试“拯救”该值并找到结束引号或分隔符(由settings.setUnescapedQuoteHandling(...)确定)。

在您的情况下,最简单的方法是将引号字符设置为'甚至\0,如果您的输入无论如何都不必处理引用值。有了这个,你应该得到你期望的"INCOME"."Taxable"

希望这有帮助

答案 1 :(得分:0)

这看起来像是代码中的错误和放宽Univocity中的CSV规范的组合。

输入是

"INCOME"."Taxable"

不幸的是,这不是有效的CSV,因为你有一个包含嵌入式引号的字符串。正确的CSV编码将是

"INCOME"".""Taxable"

Univocity库似乎对此并不严格,并且猜测输入是一个单独的字符串(因为没有输入分隔符)。因此,在解析该字段的内部值后

INCOME"."Taxable

这是字符串的实际内容,没有在Java中使其成为字符串 literal 所需的外部引号。

然后当你把它写出来时,你忽略了添加回周围的引号,导致你看到的输出。

要点:

  1. Univocity以符合您要求的方式处理无效输入,因此您就可以了。
  2. 要解决您的问题,您必须自己放回周围的引号

    int field = 0;
    for(String s:str) {
        if (++field == 4)
            System.out.print("\"" + s + "\"");
        else
            System.out.print(s + " == ");
    }
    
  3. 这也修复了额外尾随==分隔符的其他错误。

答案 2 :(得分:0)

为什么你不能做这样的事情,我也测试了结果。请相应地调整您的代码。

您的数据:

PAL : PAL : NF : "INCOME"."Taxable"
PAL : PAL : NF : "EXPENSES"."TotalExpenses"
PAL : PAL : NF : "EXPENSES"."Exceptional"

代码:

public static void parseFile(){
        String csvFile = "file/User.csv";
            String line;
            try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {

                while ((line = br.readLine()) != null) {
                    String equal_string = line.replaceAll(":", "==");
                    String quoate_string = equal_string.replaceAll("\"\"", "\"");

                    if(quoate_string.startsWith("\"") && quoate_string.endsWith("\"")){ 
                        String final_string = quoate_string.substring(1, quoate_string.length()-1);
                        System.out.println(" final : "+final_string);
                     }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

输出:

 final : PAL == PAL == NF == "INCOME"."Taxable"
 final : PAL == PAL == NF == "EXPENSES"."TotalExpenses"
 final : PAL == PAL == NF == "EXPENSES"."Exceptional"