Regular Expressions in Clojure

Our first program demonstrates the use of regular expressions in Clojure. Here’s the full source code:

(ns regular-expressions
  (:require [clojure.string :as str]
            [clojure.java.io :as io]))

(defn main []
  ; This tests whether a pattern matches a string.
  (println (boolean (re-find #"p([a-z]+)ch" "peach")))

  ; For other regexp tasks, we'll need to create a Pattern object.
  (let [r #"p([a-z]+)ch"]
    ; Here's a match test like we saw earlier.
    (println (boolean (re-find r "peach")))

    ; This finds the match for the regexp.
    (println (re-find r "peach punch"))

    ; This also finds the first match but returns the
    ; start and end indexes for the match instead of the
    ; matching text.
    (println "idx:" (let [m (re-matcher r "peach punch")]
                      (when (re-find m)
                        [(.start m) (.end m)])))

    ; The groups function includes information about
    ; both the whole-pattern matches and the submatches
    ; within those matches.
    (println (re-groups (re-matcher r "peach punch")))

    ; To find all matches for a regexp, use re-seq.
    (println (re-seq r "peach punch pinch"))

    ; Providing a limit to re-seq is not directly supported,
    ; but we can use take to achieve a similar effect.
    (println (take 2 (re-seq r "peach punch pinch")))

    ; Our examples above had string arguments. We can also provide
    ; byte arrays as arguments.
    (println (boolean (re-find r (.getBytes "peach"))))

    ; When creating global variables with regular
    ; expressions, you can use the re-pattern function.
    (def r (re-pattern "p([a-z]+)ch"))
    (println "regexp:" (str r))

    ; The clojure.string namespace can be used to replace
    ; subsets of strings with other values.
    (println (str/replace "a peach" r "<fruit>"))

    ; The replace function allows you to transform matched
    ; text with a given function.
    (println (str/replace "a peach" r #(str/upper-case %))))

(main)

To run the program, save it as regular_expressions.clj and use clojure command:

$ clojure regular_expressions.clj
true
true
[peach ea]
idx: [0 5]
[peach ea]
([peach ea] [punch un] [pinch in])
([peach ea] [punch un])
true
regexp: #"p([a-z]+)ch"
a <fruit>
a PEACH

This example demonstrates various ways to use regular expressions in Clojure. It covers pattern matching, finding matches, working with groups, replacing text, and more. The Clojure standard library and the clojure.string namespace provide rich support for working with regular expressions.

For a complete reference on Clojure regular expressions, check the clojure.core and clojure.string API docs.