10. Regular Expression Functions

The regex/ namespace uses regular expressions with leftmost-first matching. Patterns support literal text, character classes, Unicode-aware shorthand classes, alternatives, numbered and named captures, anchors, and greedy or lazy repetition. Backreferences and lookaround are not supported; PEG provides capture-dependent matching and lookahead for grammar-oriented parsing. Matching uses a non-backtracking algorithm with work proportional to the input length for a fixed pattern. Choice and capture priority follow Go/RE2-style leftmost-first matching, including when a repeated group can match empty text. A #re literal contains a pattern string and has a distinct regex runtime type. Evaluating it compiles the pattern; an invalid pattern produces an error. Quoting a literal preserves source data without compiling it. Regex values retain their original pattern text for formatting and compare by that text. Matching uses UTF-8 and Unicode properties for shorthand classes by default. Unicode category escapes \p{...} and \P{...} support L, Lu, Ll, N, Nd, Mn, Pc, Z, and Zs, and their long names. Leading flag groups enable Unicode simple case folding ((?i)), multiline anchors ((?m)), and matching newlines with dot ((?s)). Flags may be combined, as in (?im). Scoped flag groups are not supported. The \C byte-matching construct is rejected because captures must not split a UTF-8 code point. re denotes a compiled pattern. Literal text operations use strings/.

Functions that return matches accept an optional final options map, tagged with named, indices, or both. The named tag selects a map of named captures, with {} when the pattern has no named groups. The indices tag returns zero-based, start-inclusive, end-exclusive code-point ranges instead of text. With indices and no capture groups, the result is a single range; with groups, it is a list of ranges. Combine the tags to map names to ranges. An unmatched capture is null. Without options, regex/groups defines the result format.

(regex/find #re "(?<year>[0-9]{4})" "2026" <named>)
; {year "2026"}
(regex/find #re "(?<year>[0-9]{4})" "2026" <named indices>)
; {year [0 4]}

Table of Contents

10.1. Regex functions ↑

10.1.1. regex/pattern ↑

Function

(regex/pattern s) → pattern

Returns a compiled pattern for string s, or s unchanged if it is already a pattern. Invalid patterns produce an error.

10.1.2. regex/matcher ↑

Function

(regex/matcher re s) → matcher

Returns a new mutable matcher for re in string s, for use with regex/find and regex/groups. A matcher is an opaque value owned by its runtime. It can be passed between evaluations in that runtime, but it cannot be serialized or used in another runtime. The current match is cleared when a search reaches the end without a match.

10.1.3. regex/find ↑

Function

(regex/find matcher [opts]) → string, list, map, or null
(regex/find re s [opts]) → string, list, map, or null

Returns the next match from matcher, or the first match of re in string s. Returns null if there is no match.

The matcher form advances matcher. The pattern and string form starts a fresh search. Results use the capture format of regex/groups.

10.1.4. regex/groups ↑

Function

(regex/groups matcher [opts]) → string, list, or map

Returns the current match from matcher without advancing it. Without options and with no capture groups, returns the matched string. Otherwise, returns a list containing the full match followed by each capture in group-number order. An unmatched group is null. Without a current match, produces an error.

10.1.5. regex/matches ↑

Function

(regex/matches re s [opts]) → string, list, map, or null

Returns the match if re matches the entire string s, otherwise null. Results use the capture format of regex/groups.

10.1.6. regex/find-all ↑

Function

(regex/find-all re s [opts]) → list

Returns an eager list of successive, non-overlapping matches of re in string s. Each item uses the capture format of regex/groups. Returns an empty list if there are no matches. After an empty match, the search first tries a nonempty match at the same position; if there is none, it advances by one code point.

10.1.7. regex/split ↑

Function

(regex/split s re) → list
(regex/split s re limit) → list

Returns a list of parts of string s split on matches of re. The integer limit defaults to zero. A positive limit permits at most that many parts, with the unsplit suffix in the last part. Zero omits trailing empty strings. A negative limit preserves them. A zero-width match at the start of s does not create a leading empty part. If no split occurs, the result contains s as its only part.

10.1.8. regex/replace ↑

Function

(regex/replace s re replacement [opts]) → string

Returns string s with all non-overlapping matches of re replaced by replacement.

replacement is a string or a function of the match. In a replacement string, $1, $2, etc. substitute captured groups. $0 substitutes the whole match. A backslash escapes the next character; an unmatched capture substitutes an empty string. When a match is replaced, an invalid group number or a trailing backslash produces an error. When digits follow a group number, the longest valid group number is used. Use regex/quote-replacement for literal replacement text. A function receives each match in regex/groups format, in search order, and must return a string, which is inserted literally. The optional result options select the argument format for a function replacement. Result options are invalid for a string replacement.

10.1.9. regex/replace-first ↑

Function

(regex/replace-first s re replacement [opts]) → string

Returns string s with the first match of re replaced by replacement. Uses the replacement rules of regex/replace.

10.1.10. regex/quote-replacement ↑

Function

(regex/quote-replacement replacement) → string

Returns string replacement escaped for literal use with regex/replace or regex/replace-first.