带有转义逗号的clojure csv

时间:2013-04-25 12:47:08

标签: parsing csv clojure

我正在尝试使用转义逗号解析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"] 有人知道可以做到这一点的图书馆吗?

提前致谢

2 个答案:

答案 0 :(得分:6)

你并不是在解析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"])

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

答案 1 :(得分:1)

你有一个很好的借口来编写自己的解析器:-)。
您可以使用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"])