在忽略各列

时间:2015-06-19 19:18:02

标签: regex scala parsing csv

我正在尝试用逗号分隔csv字符串作为分隔符。

val string ="A,B,"Hi,There",C,D"

我无法使用string.split(","),因为它会将"Hi,There"拆分为两个不同的列。我可以使用正则表达式来解决这个问题吗?我来到scala-csv parser,我不想使用它。我希望有更好的方法来解决这个问题。我知道这不是一个小问题。如果人们可以分享他们解决这个问题的方法,那将会很有帮助。

3 个答案:

答案 0 :(得分:3)

我同意Jeronimo Backes,csv解析并不简单,使用库而不是重新发明轮子要好得多。

除了uniVocity-parsers之外,还有一些其他更多的scala定向库(指出底层解析器):

product-collections,我自己的项目,针对与univocity相同的数据进行了充分测试,也针对csv spectrum进行了测试。它是强类型,无反射并与scala-js兼容。它是tested for performance against most of the java equivalents.

列出的其他项目都有自己的优势。 Scala-csv很难在没有垫片的情况下从java调用,所以尽管我在内部对它进行了测试,但我无法对csv-parsers-comparison进行拉取请求。

产品集合用于利用opencsv,但为了使其与scala-js兼容,它现在包含一个本机解析器。在我测试的所有场景中,解析器的性能优于opencsv(速度,正确性)。

答案 1 :(得分:2)

使用uniVocity-parsers CsvParser而不是手动解析它。 CSV比你想象的要难得多,还有很多角落要覆盖。你找到了一个。简而言之,您需要一个库来可靠地读取CSV。 uniVocity-parsers被其他Scala项目使用(例如spark-csv)

我将在这里使用普通Java做一个例子,因为我不知道Scala,但你会明白这个想法:

public static void main(String ... args){
    CsvParserSettings settings = new CsvParserSettings(); //many options here, check the documentation
    CsvParser parser = new CsvParser(settings);
    String[] row = parser.parseLine("A,B,\"Hi,There\",C,D");
    for(String value : row){
        System.out.println(value);
    }
}

输出:

A
B
Hi,There
C
D

披露:我是这个图书馆的作者。它是开源和免费的(Apache V2.0许可证)。

答案 2 :(得分:-1)

这个正则表达式涵盖了你的例子,可能还包括其他人,但肯定不健全:

(?:,?(".+?"))|(?:,?(.+?),?)

这是一个关于regex101的演示:https://regex101.com/r/wM7uW4/1