如何在csv文件中转义String []数组中的逗号?

时间:2018-05-09 09:44:09

标签: java arrays string csv

我正在使用apache commons.csv.CSVparser。我想在csv记录中使用String数组,例如:

"\"[\"54bb051e-3d12-11e5-91cd-b8f6b11b7feb\",\"472a9748-3d12-11e5-91cd-b8f6b11b7feb\"]\",Hallo,114058,Leon,31,\"     \",8400,bar,FOO";
        CSVParser csvParser = CSVFormat.DEFAULT
                .withDelimiter(CSV_SEPARATOR).withQuote(null)
                .withFirstRecordAsHeader()
                .parse(new StringReader(line));

如何转义String []数组中的逗号?读取记录后,Strings会被拆分为java数组。

我试过了:

@Test
    public void processLine() throws Exception {
        String line = "Ids,Info.name,Info.number,address.street,address.number,address.bus,address.postalcode,address.city," +
                "address.country\n" +
                "\"[\"\"54bb051e-3d12-11e5-91cd-b8f6b11b7feb\"\",\"\"472a9748-3d12-11e5-91cd-b8f6b11b7feb\"\"]\",Hallo,114058,Leon,31,\"     \",8400,foo,BAR";
        CSVParser csvParser = CSVFormat.DEFAULT
                .withDelimiter(CSV_SEPARATOR).withQuote(null)
                .withFirstRecordAsHeader()
                .parse(new StringReader(line));

String []的逗号仍然被视为分隔符。

2 个答案:

答案 0 :(得分:1)

您需要正确转义CSV内容。试试这个: "\"[\"\"54bb051e-3d12-11e5-91cd-b8f6b11b7feb\"\",\"\"472a9748-3d12-11e5-91cd-b8f6b11b7feb\"\"]\",Hallo,114058,Leon,31,\" \",8400,bar,FOO"

因为混合使用Java和CSV,转义会变得混乱。在java中,你需要用\"来转义双引号,在CSV上你需要双引号来逃避它。最后,您需要\"\"来获取字符串上的输出""。最终的字符串如下所示:"[""54bb051e-3d12-11e5-91cd-b8f6b11b7feb"",""472a9748-3d12-11e5-91cd-b8f6b11b7feb""]",Hallo,114058,Leon,31," ",8400,bar,FOO。成为CSV上的第一个值:["54bb051e-3d12-11e5-91cd-b8f6b11b7feb","472a9748-3d12-11e5-91cd-b8f6b11b7feb"]

此外,您的字符串不包含标题,因此您需要注意withFirstRecordAsHeader()

此:

CSVParser csvParser = CSVFormat.DEFAULT.withDelimiter(',').withQuote('"').parse(new StringReader(
        "\"[\"\"54bb051e-3d12-11e5-91cd-b8f6b11b7feb\"\",\"\"472a9748-3d12-11e5-91cd-b8f6b11b7feb\"\"]\",Hallo,114058,Leon,31,\"     \",8400,bar,FOO"));
System.out.println(csvParser.getRecords().get(0).get(0));

将输出以下字符串:

["54bb051e-3d12-11e5-91cd-b8f6b11b7feb","472a9748-3d12-11e5-91cd-b8f6b11b7feb"]

此字符串可用于解析为String []。

答案 1 :(得分:0)

您不应该生成自己的CSV行进行测试,您已经拥有了正确创建它的库。你有想法使用Apache Commons来读取CSV而不是创建它。

使用CSVPrinter将"转义"如果需要,则使用分隔符(通过转义,您可以按格式允许的方式双引号值)

//Get a printer on the System.out
CSVPrinter printer = CSVFormat.DEFAULT.withHeader("A", "B").printer();
// Create the pojos
List<POJO> pojos = new ArrayList<>();
pojos.add(new POJO("foo", "bar"));
pojos.add(new POJO("far", "boo"));
pojos.add(new POJO("for", "bao"));
pojos.add(new POJO("test,", "comma"));

for(POJO p : pojos) {
    printer.printRecord(p.a, p.b);
}
  

A,B
  FOO,酒吧
  到目前为止,嘘
  对于,宝
  &#34;测试,&#34;,逗号

使用POJO类

public class POJO{
    String a;
    String b;

    public POJO(String a, String b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public String toString() {
        return "POJO [a=" + a + " ## b=" + b + "]";
    }
}

注意:这可能不是库的完美用法,我只使用过一次(现在),但这是为了向您展示这可以/应该使用API​​而不是创建自己的&#34; CSV&#34;线

为了表明这将正确恢复,请使用Appendable存储CSV:

StringBuffer sb = new StringBuffer();
CSVPrinter printer = CSVFormat.DEFAULT.withHeader("A", "B").print(sb);
List<POJO> pojos = new ArrayList<>();
pojos.add(new POJO("foo", "bar"));
pojos.add(new POJO("far", "boo"));
pojos.add(new POJO("for", "bao"));
pojos.add(new POJO("test,", "comma"));

for(POJO p : pojos) {
    printer.printRecord(p.a, p.b);
}

System.out.println("PRINTER");
System.out.println(sb.toString());
  

PRINTER
  A,B
  FOO,酒吧
  到目前为止,嘘
  对于,宝
  &#34;测试&#34;,逗号

解析String并创建POJO:

CSVParser parser = CSVFormat.DEFAULT
                .withFirstRecordAsHeader()
                .parse(new StringReader(sb.toString()));

System.out.println("PARSER");
parser.getRecords().stream().map(r -> new POJO(r.get(0), r.get(1))).forEach(System.out::println);
  

PARSER
  POJO [a = foo ## b = bar]
  POJO [a =远## b = boo]
  POJO [a = for ## b = bao]
  POJO [a = test,## b =逗号