解析CSV到Kotlin列表

时间:2019-01-01 18:04:21

标签: kotlin

我有点困惑。 我的csv行使用双引号(“”)作为分组字符串,并且想要转换为Kotlin列表。 但是,它会生成一个大小为1的单个数组。 我希望能够得到这个小组,假设在位置2。

val s = "John Doe, 13, \"Subject 1, Subject 2, Subject 3\""
var list: List<String> = s.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")
Log.d("size:", list.size.toString() + " - subjects:" + list[2])

这给了我错误

java.lang.IndexOutOfBoundsException: Index: 2, Size: 1

4 个答案:

答案 0 :(得分:2)

给定的正则表达式工作正常。当前,您尝试在原始正则表达式中将字符串s拆分为分隔符,而s中不存在此分隔符。只需将.toRegex()添加到正则表达式即可。

val s = "John Doe, 13, \"Subject 1, Subject 2, Subject 3\""
var list: List<String> = s.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)".toRegex())
Log.d("size:", list.size.toString() + " - subjects:" + list[2])

答案 1 :(得分:1)

"分隔,您会看到一个带有size = 3的列表
而您需要的是index = 1
然后,您需要将index = 0项除以,来获得名称和数字:

val s = "John Doe, 13, \"Subject 1, Subject 2, Subject 3\""
val list: List<String> = s.split("\"")
val listStart = list[0].split(",")
val subjects = list[1].trim()
val name = listStart[0].trim()
val number = listStart[1].trim()

另一种方法,如果您不需要列表,而只需要值:

val s = "John Doe, 13, \"Subject 1, Subject 2, Subject 3\""
val subjects = s.substringAfter("\"").substringBefore("\"").trim()
val name = s.substringBefore(",").trim()
val number = s.substringAfter(",").substringBefore(",").trim()

println("name: " + name)
println("number: " + number)
println("subjects: " + subjects)

将打印:

name: John Doe
number: 13
subjects:Subject 1, Subject 2, Subject 3

答案 2 :(得分:1)

这有帮助吗?由于我没有提出任何实际断言,因此测试并不多,但也许足以使您了解这个想法。

@Test
fun should_tolerate_quoted_commas_in_third_column() {
    val s = "John Doe, 13, \"Subject 1, Subject 2, Subject 3\""
    val pattern = Pattern.compile(",")
    s.split(regex=pattern, limit=3).forEach( System.out::println )
}

输出:

John Doe
 13
 "Subject 1, Subject 2, Subject 3"

编辑1:

类似地...

@Test
fun should_make_list_from_quoted_string_in_third_column() {
    val s = "John Doe, 13, \"Subject 1, Subject 2, Subject 3\""
    val outerList = s.split(regex = Pattern.compile(","), limit = 3)
    outerList[2].replace("\"","").split(",").forEach( System.out::println )
}

答案 3 :(得分:1)

我建议自己解析,但要使用现有的库。 (例如,我发现Apache Commons CSV在Kotlin中易于使用。)

尽管编写解析代码很有趣,而且CSV看起来很简单,但是它具有足够的复杂性和变体,除非您自己创建它,否则可能会错过某些情况。 (不仅是转义的引号,还有其他的转义字符,嵌套的引号,包括换行符,注释行的字段...还有我最喜欢的陷阱:MS Excel使用计算机的列表分隔符,该分隔符可以是分号或另一个字符而不是逗号来分隔字段!)

相信我,我去过那里...