Я думаю, что это должно работать, быть полностью общим и не требовать собственного читателя / парсера:
(defn is-clojure-whitespace? [c]
(or (Character/isSpace c)
(= \, c)))
(defn whitespace-split
"Returns a map of true -> (maximal contiguous substrings of s
consisting of Clojure whitespace), false -> (as above, non-whitespace),
:starts-on-whitespace? -> (whether s starts on whitespace)."
[s]
(if (empty? s)
{}
(assoc (group-by (comp is-clojure-whitespace? first)
(map (partial apply str)
(partition-by is-clojure-whitespace? s)))
:starts-on-whitespace?
(if (is-clojure-whitespace? (first s)) true false))))
(defn string-assoc-in [s coords subst]
(let [{space-blocks true
starts-on-whitespace? :starts-on-whitespace?}
(whitespace-split s)
s-obj (assoc-in (binding [*read-eval* false] (read-string s))
coords
(binding [*read-eval* false] (read-string subst)))
{non-space-blocks false}
(whitespace-split (pr-str s-obj))]
(apply str
(if starts-on-whitespace?
(interleave space-blocks (concat non-space-blocks [nil]))
(interleave non-space-blocks (concat space-blocks [nil]))))))
Пример:
user> (string-assoc-in "[:a [:b,, :c]]" [1 0] ":new")
"[:a [:new,, :c]]"
Обновление: Ой, поймал ошибку:
user> (string-assoc-in "[:a [:b,, :c\n]]" [1 0] ":new")
"[:a [:new,, :c]]\n"
Мне бы понравилось, если бы это не имело значения, но я думаю, мне придется попытаться что-то с этим сделать ... вздох