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