我想编写一个函数replace-several
,它接收一个字符串和一组替换并应用所有替换(替换部分会看到之前替换的结果)。
我想到了以下界面:
(replace-several "abc" #"a" "c"
#"b" "l"
#"c" "j"); should return "jlj"
两个问题:
备注:要进行一次替换,clojure.string中有replace
个可用。
答案 0 :(得分:12)
使用replace
,reduce
和partition
实施@ kotarak的建议:
(defn replace-several [content & replacements]
(let [replacement-list (partition 2 replacements)]
(reduce #(apply string/replace %1 %2) content replacement-list)))
; => (replace-several "abc" #"a" "c" #"b" "l" #"c" "j")
"jlj"
答案 1 :(得分:9)
所以你有replace
,reduce
和partition
。从这些构建基块中,您可以构建replace-several
。
答案 2 :(得分:4)
这是另一个镜头但不同的输出结果,这个使用正则表达式引擎功能,因此它可能更快,界面也不同,因为它将键映射到替换字符串。我提供这个,以防有问题的人可能会有用。
(defn replace-map
"given an input string and a hash-map, returns a new string with all
keys in map found in input replaced with the value of the key"
[s m]
(clojure.string/replace s
(re-pattern (apply str (interpose "|" (map #(java.util.regex.Pattern/quote %) (keys m)))))
m))
所以用法就是这样:
(replace-map "abc" {"a" "c" "b" "l" "c" "j"})
=> “CLJ”
答案 3 :(得分:4)
我迟到了这个派对,但是为了它的价值,我认为大多数惯用的方法是使用线程和多个替换:
(require '[clojure.string :refer [replace])
(-> "abc"
(replace #"a" "c")
(replace #"b" "l")
(replace #"c" "j"))
;=> "jlj"
这一点的含义非常清楚,但避免多次输入“替换”是很好的。
答案 4 :(得分:1)
你可以使用reduce with replace:
(defn replace-several
[str & replacements]
(reduce (fn [s [a b]]
(clojure.string/replace s a b))
str
(partition 2 replacements)))
(replace-several "abc"
#"a" "c"
#"b" "l"
#"c" "j")
答案 5 :(得分:1)
(str/escape "abc" {\a "c" \b "l" \c "j"})
; => "clj"
文档escape
答案 6 :(得分:0)
首先猜测..
(defn replace-several [string & mappings]
(loop [grouped-mappings (partition 2 mappings) string string]
(if (empty? grouped-mappings)
string
(let [[re rep] (first grouped-mappings)]
(recur (rest grouped-mappings) (clojure.string/replace string re rep))))))
; => (replace-several "abc" #"a" "c" #"b" "l" #"c" "j")
"jlj"
答案 7 :(得分:0)
就我个人而言,我不会为此创建单独的函数,因为它只是现有Clojure函数的组合:
(reduce-kv clojure.string/replace "Hello" {#"[A-Z]" "J", "o" "y"}
;=> "Jelly"
当然,如果你想要varargs和界面,那么:
(defn replace-many [string & {:as rplcmnts}]
(reduce-kv clojure.string/replace string rplcmnts))