【问题标题】:Parsing a CSV string while ignoring commas inside the individual columns解析 CSV 字符串,同时忽略各个列中的逗号
【发布时间】:2015-09-05 21:14:47
【问题描述】:

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

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

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

【问题讨论】:

  • CSV 解析并不像您意识到的那样简单。因此,这种格式可能过于宽泛,无法提供完整的答案,询问工具在 SO 上是题外话,所以我认为这个问题不适合这个网站。
  • @Gábor 你误会了。我不想使用任何工具。我希望人们在这里分享逻辑或任何好的方法。我可以使用像scala-csv 这样的解析器来完成这个任务。但是,我想要一种开放的逻辑方法来解决这个问题。如果人们在这里分享方法,我认为这个问题会对很多人有所帮助。
  • @COSTA 解决这个问题的合乎逻辑的方法是使用已建立的库,因为 csv 解析非常重要。
  • 使用 Scala 的解析器组合器 API,您可以编写一个符合 RFC 4180 的解析器,并且少于 30 个 LOC。但如前所述,您可以使用现有的解析器让您的生活更轻松。

标签: regex scala parsing csv


【解决方案1】:

我同意 Jeronimo Backes 的观点,csv 解析并非易事,使用库比重新发明轮子要好得多。

除了uniVocity-parsers,还有一些其他更面向scala的库可用(指示底层解析器):

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

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

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

【讨论】:

    【解决方案2】:

    为此使用uniVocity-parsersCsvParser 而不是手动解析它。 CSV 比您想象的要困难得多,并且有许多极端情况需要涵盖。你刚刚找到了一个。简而言之,您需要一个库来可靠地读取 CSV。其他 Scala 项目(例如 spark-csv)使用 uniVocity-parsers

    我将在这里举一个使用纯 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 许可)。

    【讨论】:

      【解决方案3】:

      这个正则表达式涵盖了您的示例,可能还有其他示例,但肯定不可靠:

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

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

      【讨论】:

        猜你喜欢
        • 2011-10-10
        • 2017-05-07
        • 1970-01-01
        • 2014-02-26
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 2021-07-09
        相关资源
        最近更新 更多