簡體   English   中英

使用Clojure的read-string獲取正在讀取的字符串的“未讀”部分

[英]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]"

讀者相當於rest還是drop

你可以用串中StringReader ,然后包裹在一個PushbackReader ,然后read從讀者多次。

NB。 下面的示例使用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])

https://stackoverflow.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))))

可能不是很慣用,但很簡單

(->> (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函數的doc字符串中找到,即(source read)從REPL (source read)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM