std/regex
Unicode scalar regular expressions: ordered Thompson NFA / PikeVM. Searches are O(program states * input scalars), with no backtracking. Offsets are zero-based scalar offsets; captures include group zero. Repeated searches (find_all, split, replacements) have Rust regex’s iterator cost: O(mn^2) in the worst case, O(mn) for bounded matches.
Regex
Regex = ( RegexError
RegexError = (position = Int, reason = String) Match
Match = (start = Int, end = Int, text = String) Captures
Captures = ( compile
Compiles to an immutable NFA, or an error at a scalar position.
regex.compile("(?<word>\\w+)").
compile = (pattern : String) -> Result(Regex, RegexError) { is_match
Whether any match exists, including an empty match.
is_match = (regex : Regex, input : String) -> Bool { find
Finds the leftmost-first match: regex.find(re, "abc").
find = (regex : Regex, input : String) -> Option(Match) { find_all
Non-overlapping matches, advancing by scalars after empty matches.
find_all = (regex : Regex, input : String) -> List(Match) { captures
The leftmost-first capture set, including all participating groups.
captures = (regex : Regex, input : String) -> Option(Captures) { group
Capture by index; zero is the full match. An unmatched group is None.
regex.group(captures, 1).
group = (captures : Captures, index : Int) -> Option(Match) { named
Capture by name, or None for an unknown/unmatched name.
named = (captures : Captures, name : String) -> Option(Match) { replace
Replaces the first match; $1, ${name}, and $$ expand captures/dollar.
Missing groups expand to empty text. $1x names group 1x; use ${1}x.
replace = (regex : Regex, input : String, with : String) -> String { replace_all
Replaces all non-overlapping matches with capture expansion.
replace_all = (regex : Regex, input : String, with : String) -> String { split
Splits around every non-overlapping match, preserving empty pieces.
split = (regex : Regex, input : String) -> List(String) {