1 minute read

Today I saw a clever bit of Clojure code involving clojure.string/replace, that reminded me how powerful the Clojure standard library is. I guess pretty much everyone knows that replace is normally used to replace some part of a string using a regular expression to describe what exactly to replace:

(str/replace "OCaml rocks!" #"([Hh]askell)|([Oo][Cc]aml)" "Clojure")
;; => "Clojure rocks!"

;; we can refer to the match groups in the replacement string
(str/replace "Haskell rocks!" #"([Hh]askell)|([Oo][Cc]aml)" "$1 is nice, but Clojure")
;; => "Haskell is nice, but Clojure rocks!"

Pretty useful and pretty straightforward. But wait, there’s more! I had forgotten you can actually use a function for the replacement, which allows us to do more sophisticated things. Here’s how we can capitalize every word with 5 or more letters in a string:

(str/replace "master of Clojure is pulling the strings" #"\w{5,}" str/upper-case)

If you’ve got more match groups in your regular expression you can use all of them in the function that you’re using to generate the replacements:

(str/replace "pom kon sor" #"(.)o(.)" (fn [[_ a b]] (str (str/upper-case a) "-o-" (str/upper-case b))))
"P-o-M K-o-N S-o-R"

Note here the use of deconstructing to account that each match is essentially a vector of the full match and each group match (e.g. ["pom" "p" "m"]).

That’s I have for you today! Feel free to share with me more fun usages of replace!