Strings, Regular Expressions and I/O
20.1 clojure.string
(require '[clojure.string :as str])
(str/upper-case "hi") (str/lower-case "HI") (str/capitalize "hello")
(str/trim " x ") (str/triml " x") (str/trimr "x ")
(str/split "a,b,c" #",") ; ["a" "b" "c"]
(str/split-lines "a\nb") ; ["a" "b"]
(str/join ", " ["a" "b" "c"]) ; "a, b, c"
(str/replace "hello world" "o" "0") ; "hell0 w0rld"
(str/replace "a1b22" #"\d+" "#") ; "a#b#"
(str/replace "john smith" #"\b\w" str/upper-case) ; "John Smith"
(str/includes? "hello" "ell") (str/starts-with? "hello" "he") (str/ends-with? "hello" "lo")
(str/blank? " ") ; true
(str/reverse "abc") ; "cba"
(str/index-of "hello" "l") ; 2
(str/escape "a<b" {\< "<"}) ; "a<b"
20.2 Regular Expressions
(re-find #"\d+" "abc 123 def 45") ; "123"
(re-seq #"\d+" "abc 123 def 45") ; ("123" "45")
(re-matches #"(\d{4})-(\d{2})" "2025-10") ; ["2025-10" "2025" "10"]
(re-find #"(?i)hello" "HELLO there") ; "HELLO"
(let [[_ year month] (re-matches #"(\d{4})-(\d{2})" "2025-10")] [year month])
(re-pattern (str "\\b" "word" "\\b")) ; build a pattern dynamically
20.3 Files and I/O
(require '[clojure.java.io :as io])
(spit "notes.txt" "Hello\n") ; write (overwrite)
(spit "notes.txt" "More\n" :append true)
(slurp "notes.txt") ; read the whole file
(slurp "https://example.com") ; slurp also reads URLs
(with-open [rdr (io/reader "notes.txt")]
(doall (line-seq rdr))) ; realize lines before the reader closes
(with-open [w (io/writer "out.txt")]
(.write w "line 1\n"))
(.exists (io/file "notes.txt"))
(.mkdirs (io/file "out/nested"))
(file-seq (io/file "src")) ; recursive directory listing
(io/copy (io/file "a.txt") (io/file "b.txt"))
(io/resource "config.edn") ; a file on the classpath (resources/)
(println "stdout") (binding [*out* *err*] (println "stderr"))
(read-line) ; read from *in*
(printf "%s=%d%n" "x" 1)
(with-out-str (println "captured")) ; "captured\n"