更新:传递:
#",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"
到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
,因此我们需要避免在split
中遇到逗号时触发"Newell, Gabe"
函数。
我们需要一个将某个字符串拆分的函数,除非某个字符在引号中。
答案 0 :(得分:0)
要允许字段内的分隔符(此处为,
),需要引用这些字段。
您在此处使用\"
执行的操作转义引号(unix样式,引号也可以使用其他引号进行转义)。
因此,允许字段内的,
:
"Hello,"Newell, Gabe",world"
当然,那些外部引号不应该是csv的一部分。
编辑问题后Udate :
以上数据在文件中实际上看起来像Hello,“Newell, Gabe“,世界,所以我们需要避免触发分裂功能 在“Newell,Gabe”中出现了逗号。
Hello,"Newell, Gabe",world
这是完全有效的csv,但如果使用,
上的纯分割功能处理此问题,则会遇到麻烦。
一种选择可能是使用其他分隔符,例如|
或;
。
更新2 :
所以我需要一个新功能,将CSV字符串拆分为字段,除非 逗号是引号(我无法更改数据集)。我怎么去 关于实现这个?
对于每一行,你需要扫描每个字符,在伪代码中有点像这样(我不知道Clojure,所以我不能提供一些代码,但我用大csv文件工作了很多):
bool InsideQuotes = false;
loop through chars
if `,` and InsideQuotes == false -> new field
if `"` -> InsideQuotes = !InsideQuotes
这种方式引用字段内的引号可以使用另一个引号进行转义。例如:
Hello,"17"" monitor, Samsung",world
<强>更新强>: