如何用引号中的某些项解析逗号分隔行(CSV)?

时间:2015-09-27 01:28:15

标签: java regex scala csv

我试图使用:

解析逗号分隔的字符串
val array = input.split(",")

然后我注意到一些输入行在引号内有“,”:

data0, "data1", data2, data3, "data4-1, data4-2, data4-3", data5

*请注意,数据不是很干净,因此有些字段在引号内,而有些字段不在

如何将此行拆分为:

array(0) = data0
array(1) = data1
array(2) = data2
array(3) = data3
array(4) = data4-1, data4-2, data4-3
array(5) = data5

4 个答案:

答案 0 :(得分:5)

根据我的评论:

解析CSV文件可能因其引号周围的行为以及引号中包含的逗号和引号而非常棘手。我建议拉入一个能够很好地处理所有边缘情况的库。

您可以考虑的选项包括scala-csvtraversable-csv。或者使用像opencsv这样的Java库。

否则,如果您不想或不能使用库,可以查看this SO answerthis SO answer,了解其他人如何处理自己的CSV解析器。

答案 1 :(得分:0)

我建议使用CSV库来解析CSV数据 - 这种格式很麻烦并且很难实现。

我建议kantan.csv,主要是因为我是作者,但也因为它让你比将CSV流转换为字符串数组列表更进一步。举例来说,输入如下:

1,Foo,2.0
2,Bar,false

使用kantan.csv,你可以写:

import kantan.csv.ops._

new File("path/to/csv").asUnsafeCsvRows[(Int, String, Either[Float, Boolean])](',', false)

对结果调用toList将产生:

List((1,Foo,Left(2.0)), (2,Bar,Right(false)))

注意最后一列是浮点数还是布尔值,但这是在迭代器的每个元素的类型中捕获的。

答案 2 :(得分:0)

以下是解析CSV行的解决方案:

String[] res = row.split(";");
for (int i = 0; i < res.length; i++) {
    res[i] = deQuotes(res[i]);
}
return res;

使用REGEXP删除引号:

static final Pattern PATTERN_DE_QUOTES = Pattern.compile("(?i)^\\\"(.*)\\\"$");

static String deQuotes(String s) {
    Matcher matcher;
    if ((matcher = PATTERN_DE_QUOTES.matcher(s)).find()) {
        return matcher.group(1).replaceAll("\"\"", "\"");
    }
    return s;
}

我希望它会对你有所帮助。

答案 3 :(得分:-1)

您实际上可以使用正则表达式分割该行。

val s = """data0, "data1", data2, data3, "data4-1, data4-2, data4-3", data5"""

"""((".*?")|('.*?')|[^"',]+)+""".r.findAllIn(s).foreach(println)

顺便说一句。任何可以解析csv文件的库也可以解析单个csv行。只需将字符串包装到StringReader中即可。