【问题标题】:clojure csv with escaped comma带有转义逗号的clojure csv
【发布时间】:2013-04-19 08:56:10
【问题描述】:

我正在尝试使用转义逗号解析 clojure 中的 csv 字符串,并且在这样的字段周围没有引号

"test1\,test2,test3"

我试过这个库:

  • [org.clojure/data.csv "0.1.2"]
  • [cljcsv "1.3.1"]
  • [clojure-csv/clojure-csv "2.0.0-alpha1"]

但他们似乎都没有能力将其正确识别为["test1,test2" "test3"] 有人知道可以做到这一点的图书馆吗?

提前致谢

【问题讨论】:

  • 我和incanter 相处得很好。这可能是矫枉过正,所以你可能只想使用 OpenCSV(一个 incanter 依赖项)。
  • 我要补充一点,我相信它是一个有效的 CSV,你需要以下内容:"\"test1,test2\",test3"

标签: parsing csv clojure


【解决方案1】:

您并没有完全解析 CSV 数据,而是一些推导 of the convention(注意我没有写“标准”)。

在 CSV 中,逗号不会被转义。这是从 C/C++/Java 字符串转义泄漏到您的数据中的东西。如果是典型的 CSV,会这样写

"a,b",c

哪些 clojure-csv 支持。

user=> (csv/parse-csv (str "\"a,b\",c")) 
(["a,b" "c"])

您可能必须编写自己的解析器,或扩展上述库之一来处理这种情况。

【讨论】:

  • 谢谢。我喜欢你的评论,它不是标准的 .csv。不是。
  • 我的字段中也有双引号,用反斜杠转义。我该如何处理它们?
  • 也许您应该打开一个新问题,询问有关实现此问题的指示。它的范围比您原来的问题要大一些。
【解决方案2】:

你有一个很好的借口来编写你自己的解析器:-)。
您可以使用 Instaparse:https://github.com/Engelberg/instaparse

更新: 好的,我自己无法抗拒诱惑 :-)
更新 2: 允许在带引号的字符串中使用转义字符。

(require '[instaparse.core :as insta])

(def custom-csv
  (insta/parser
    "file = (line <eol>)* line
     line = (field <','>)* field
     eol = '\\r'? '\\n'
     <field> = plain-field | quoted-field
     quoted-field = <'\\\"'> (#'[^\"\\\\]+' | escaped-char)* <'\\\"'>
     plain-field = (field-chars | escaped-char)*
     <field-chars> = #'[^\\\\\\r\\n,\\\"]+'
     escaped-char = #'\\\\.'
    "))

(def test-str 
"test1\\,test2,test3
te\\s\\\\t4,\"te,st
5\"")

(custom-csv test-str)
; Result:
; [:file
;  [:line
;   [:plain-field "test1" [:escaped-char "\\,"] "test2"]
;   [:plain-field "test3"]]
;  [:line
;   [:plain-field "te" [:escaped-char "\\s"] [:escaped-char "\\\\"] "t4"]
;   "te,st\n5"]]

(->> (custom-csv test-str)
     (insta/transform
       {
         :file list
         :line vector
         :plain-field str
         :quoted-field str
         :escaped-char second
       }))
; Result:
; (["test1,test2" "test3"] ["tes\\t4" "te,st\n5"])

【讨论】:

  • 每个人都应该至少编写一次自己的解析器!
  • 感谢您向我指出这个库。我用它编写了一个类似于你的解析器,但做了一些简化。 (字段中没有新行......)工作得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多