2016-09-06 59 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])