liveBook · Manning

Re-seq

As explained in Clojure: The Essential Reference

re-seq is a Clojure function that returns a lazy sequence of matches for a regular expression in a string.

re-seq creates a lazy sequence of every match for a regular expression in a string or other CharSequence. Use it when re-find's first match is insufficient. section 9.3.5 section 19.10

The pattern must be a java.util.regex.Pattern, commonly written with a #"regex" reader literal; the input must be a CharSequence. Nil for either argument raises NullPointerException. An empty input returns nil. Without capturing groups, matches are strings; with groups, each match includes the captured values. section 9.3.5

Extracting captured fields

A capturing group can turn a larger match into useful fields: (let [people (re-seq #"(\\w+) (\\d{3}) \\d{3}-\\d{4}" signed-up)] {:names (map second people) :area (map last people)}) ;; {:names ("Jack" "Anna" "Charlie" "Hugo" "Jane" "Ron") ;; :area ("221" "221" "661" "661" "661" "555")}

Consuming only needed matches

Laziness supports partial consumption: (take 20 (re-seq #"\\d" pi-digits)) Only the requested portion of the match sequence needs to be produced, although the source string must already be loaded in memory. section 9.3.5

(import '[java.io InputStream]
        '[java.net URL]
        '[java.util Scanner]
        '[java.util.regex Pattern])

(defn restream-seq [^Pattern re ^InputStream is] ; #1
  (let [s (Scanner. is "UTF-8")]
    ((fn step []
       (if-let [token (.findInLine s re)]
         (cons token (lazy-seq (step)))
         (when (.hasNextLine s) (.nextLine s) (step)))))))

(defn pi-seq [is] ; #2
  (sequence
    (comp
      cat
      (map int)
      (map #(mod % 48)))
    (restream-seq #"\d{10}" is)))

(def pi-digits (URL. "https://tinyurl.com/pi-digits"))

(with-open [is (.openStream pi-digits)] ; #3
  (doall (take 20 (pi-seq is))))
;; (1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6)

Shows a stream-oriented rework for inputs too large to load as one string; ordinary re-seq itself remains string-based. section 9.3.5

How Clojure: The Essential Reference covers it

How deep it goes
Defines inputs, outputs, exceptions, groups, laziness, and memory limits, then demonstrates extraction and partial consumption.
Examples
Demonstrates numeric matches, captured contact fields, email extraction, and lazy processing of Pi digits.
What it assumes
Assumes familiarity with Clojure sequences and regular-expression patterns while showing the Pattern input form from zero.
What you can do after
Apply it via Clojure's regular-expression API to extract all matches or captured fields from character sequences.
How it connects
Connects regular expressions, capturing groups, lazy sequences, re-find, re-groups, and Matcher objects.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.