2016-09-06 30 views

回答

1

可能不是很地道,但简单

(->> (str "(" "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]" ")") 
    (read-string)) 

然后访问各个元素(你也可以使用括号)

+0

是的,那是有效的。虽然这样做有点奇怪......欢呼声 – interstar

0

如果你有字符串中的列表,您可以通过给选项保存它read-string -

(def str-list "({:a 1 :b 2} {:c 3 :d 4} [1 2 3])") 

(read-string {:read-cond :preserve} str-list) 
;;=> ({:a 1 :b 2} {:c 3 :d 4} [1 2 3]) 

可用的选项源可以在文档字符串中的read function,即发现来自REPL的(source read)

+0

'read-cond'与此完全无关。任何示例输入中都没有读者条件。 – amalloy

+0

只要没有读者条件,你是正确的。但是,选项散列允许保留字符串中的有效表单,这是OP所处的功能,不需要额外的库。也许':read-cond'的名字太窄了,但是它会根据问题所在的位置来解析字符串。 – nrako

3

您可以将字符串包装在StringReader中,然后将其包装在PushbackReader,然后read多次。

注意:下面的例子使用clojure.edn/read,因为这是一个edn专用的读取器,用于处理纯数据; clojure.core/read主要用于读取代码,并且应该从不使用与不可信输入一起使用。

(require '[clojure.edn :as edn]) 

(def s "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]") 

;; Normally one would want to use with-open to close the reader, 
;; but here we don't really care and we don't want to accidentally 
;; close it before consuming the result: 
(let [rdr (java.io.PushbackReader. (java.io.StringReader. s)) 
     sentinel (Object.)]  ; ← or just use ::eof as sentinel 
    (take-while #(not= sentinel %) 
       (repeatedly #(edn/read {:eof sentinel} rdr)))) 
;= ({:a 1, :b 2} {:c 3, :d 4} [1 2 3])