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.