我正在尝试使用转义逗号解析 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"]
有人知道可以做到这一点的图书馆吗?
提前致谢
您并没有完全解析 CSV 数据,而是对约定的一些推导(注意我没有写“标准”)。
在 CSV 中,逗号不会被转义。这是从 C/C++/Java 字符串转义泄漏到您的数据中的东西。如果是典型的 CSV,它会这样写
"a,b",c
哪个 clojure-csv 支持。
user=> (csv/parse-csv (str "\"a,b\",c"))
(["a,b" "c"])
您可能必须编写自己的解析器,或扩展上述库之一来处理这种情况。
你有一个很好的借口来编写你自己的解析器:-)。
您可以使用 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"])