使用 Clojure 的读取字符串获取正在读取的字符串的 "unread" 部分
Getting the "unread" part of a string being read with Clojure's read-string
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]"
reader 等同于 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 的文档字符串中找到,即 (source read)
来自 REPL。
您可以将字符串包装在 StringReader
中,然后将其包装在 PushbackReader
中,然后 read
从 reader 多次包装。
注意。下面的示例使用 clojure.edn/read
,因为这是一个仅用于处理纯数据的 edn reader; 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])
https://whosebug.com/users/232707/michał-marczyk
接受的答案应该是什么的 ClojureScript 版本
(require '[cljs.reader :as rdr])
(require '[cljs.tools.reader.reader-types :as reader-types])
(def s "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]")
(let [pbr (reader-types/string-push-back-reader s)
sentinel ::eof]
(take-while #(not= sentinel %)
(repeatedly #(rdr/read {:eof sentinel} pbr))))
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]"
reader 等同于 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 的文档字符串中找到,即 (source read)
来自 REPL。
您可以将字符串包装在 StringReader
中,然后将其包装在 PushbackReader
中,然后 read
从 reader 多次包装。
注意。下面的示例使用 clojure.edn/read
,因为这是一个仅用于处理纯数据的 edn reader; 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])
https://whosebug.com/users/232707/michał-marczyk
接受的答案应该是什么的 ClojureScript 版本(require '[cljs.reader :as rdr])
(require '[cljs.tools.reader.reader-types :as reader-types])
(def s "{:a 1 :b 2} {:c 3 :d 4} [1 2 3]")
(let [pbr (reader-types/string-push-back-reader s)
sentinel ::eof]
(take-while #(not= sentinel %)
(repeatedly #(rdr/read {:eof sentinel} pbr))))