【发布时间】:2015-12-26 20:45:29
【问题描述】:
更新:通过这个:
#",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"
到clojure.string/split 解析CSV。
更新:我需要一个匹配所有不在引号中的逗号的正则表达式,其格式可供clojure.string/split 使用。
我在 Clojure 中写了一个 CSV 解析函数:
(defn parse-csv [data schema]
(let [split-data (clojure.string/split data #",")]
(loop [rm-data split-data
rm-keys (:keys schema)
rm-trans (:trans schema)
final {}]
(if (empty? rm-keys)
final
(recur (rest rm-data)
(rest rm-keys)
(rest rm-trans)
(into final
{(first rm-keys)
((first rm-trans) (first rm-data))}))))))
schema 只是一个哈希映射,由关键字列表和函数列表(应用于它们各自的值)组成。这用于定义输出哈希映射的外观。
这是一个例子:
(def schema {:keys [:foo :bar :baz] :trans [identity read-string identity]})
(parse-csv "Hello,42,world" schema) ;; returns {:foo "Hello", :bar 42, :baz "world"}
但是,如果我们这样做:
(def schema {:keys [:foo :bar :baz] :trans [identity identity identity]})
(parse-csv "Hello,\"Newell, Gabe\",world" schema) ;; returns {:foo "Hello" :bar "\"Newell" :baz "Gabe\""}
事情变得一团糟,“世界”这个词被忽略了。结果应该如下所示:
{:foo "Hello" :bar "\"Newell, Gabe\"" :baz "world"}
上述数据,在一个文件中,实际上看起来像Hello,"Newell, Gabe",world,所以我们需要避免在遇到"Newell, Gabe"中的逗号时触发split函数。
我们需要一个函数,将字符串按特定字符分割除非特定字符在引号中。
【问题讨论】:
-
为了在带引号的字符串中允许逗号,您需要先拆分字符串,然后用剩下的内容创建字段。或者使用真正的解析器。
-
github.com/clojure/data.csv 使用默认选项正确读取:
(require '[clojure.data.csv :as csv]) (csv/read-csv "Hello,\"Newell, Gabe\",world") ; => (["Hello" "Newell, Gabe" "world"])