Clojure的(讀取字符串)非常有用。獲取用Clojure的讀取字符串讀取的字符串的「未讀」部分
例如。
(read-string "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]")
會給我的第一個對象,該{:a 1 :b 2}
但我怎麼能得到的字符串即休息。 "{:c 3 :d 4} [1 2 3]"
什麼是rest
或drop
的讀者等價物?
Clojure的(讀取字符串)非常有用。獲取用Clojure的讀取字符串讀取的字符串的「未讀」部分
例如。
(read-string "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]")
會給我的第一個對象,該{:a 1 :b 2}
但我怎麼能得到的字符串即休息。 "{:c 3 :d 4} [1 2 3]"
什麼是rest
或drop
的讀者等價物?
可能不是很地道,但簡單
(->> (str "(" "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]" ")")
(read-string))
然後訪問各個元素(你也可以使用括號)
如果你有字符串中的列表,您可以通過給選項保存它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)
。
您可以將字符串包裝在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])
是的,那是有效的。雖然這樣做有點奇怪......歡呼聲 – interstar