ClojureCLR v2.9 Release Notes

  • clojure.string/replace and clojure.string/replace-first are now consistent in the way that they handle the replacement strings: all characters in the replacement strings are treated literally, including backslash and dollar sign characters.

    user=> (require '[clojure.string :as s])
    
    user=> (s/replace-first "munge.this" "." "$")
    ;=> "munge$this"
    
    user=> (s/replace "/my/home/dir" #"/" (fn [s] "\\"))
    ;=> "\\my\\home\\dir"
    

    👻 There is one exception, which is described in the doc strings. If you call these functions with a regex to search for and a string as the replacement, then dollar sign and backslash characters in the replacement string are treated specially. Occurrences of $1 in the replacement string are replaced with the string that matched the first parenthesized subexpression of the regex, occurrences of $2 are replaced with the match of the second parenthesized subexpression, etc.

    user=> (s/replace "x12, b4" #"([a-z]+)([0-9]+)" "$1 <- $2")
    ;=> "x <- 12, b <- 4"
    

    Individual occurrences of $ or \ in the replacement string that you wish to be treated literally can be escaped by prefixing them with a \. If you wish your replacement string to be treated literally and its contents are unknown to you at compile time (or you don't wish to tarnish your constant string with lots of backslashes), you can use the new function clojure.string/re-quote-replacement to do the necessary escaping of special characters for you.

    user=> (s/replace "x12, b4" #"([a-z]+)([0-9]+)"
                         (s/re-quote-replacement "$1 <- $2"))
    ;=> "$1 <- $2, $1 <- $2"