Module regex/index

regex/index
Stability: unstable. The Rust-shaped names landed only in v0.2.28 (#517 — `test` → `is_match`, `exec` → `find`, `match_all` → `find_all`, and the flag string split out into `new_with_flags`), and three shapes are still wrong rather than merely young: - `split` interleaves capture groups into its result and emits the literal string `"undefined"` for a group that did not participate — JavaScript's shape, described at the method and filed as `issues/stddoc-str-regex-split-emits-the-literal-string-undefined.md`. - The `g` and `u` flags are accepted and ignored (`issues/stddoc-str-regex-g-and-u-flags-are-silently-ignored.md`), so `new_with_flags(p, "g")` reads as if it changed `replace` and does not. - `i` folds ASCII only, so an `i` pattern does not match `É` with `é`. Each fix changes behaviour, so none of them is additive, and the module cannot freeze before they are decided. What IS settled: `Regex` / `RegexMatch` / `RegexMatchIter` / `RegexError` as the whole public surface, byte offsets everywhere, `Result` rather than exceptions from `new`, no separate `captures` (a `RegexMatch` always carries its groups), and the `Pattern` impl that lets a compiled regex be passed to any `String` search method. — stable modules only change additively; this one may still change.

Regular expression engine with an NFA-based virtual machine.

The public surface of the whole package is the four names this module exports: Regex, RegexMatch, RegexMatchIter and RegexError. The sibling modules (parser, node, compiler, vm, flags, unicode) are internals — they export only what their siblings consume, and nothing in them is covered by the stability promise.

Example

{ Regex } :: import("std/regex");

re := Regex.new_with_flags(`(\w+)@(\w+)`, `i`).unwrap();
match(
  re.find(`mail Ada@Example`),
  .Some(m) => println(m.group(usize(1)).unwrap()),
  .None => println(`no match`)
);

Stability

unstable. The Rust-shaped names landed only in v0.2.28 (#517 — testis_match, execfind, match_allfind_all, and the flag string split out into new_with_flags), and three shapes are still wrong rather than merely young:

  • split interleaves capture groups into its result and emits the literal string "undefined" for a group that did not participate — JavaScript's shape, described at the method and filed as issues/stddoc-str-regex-split-emits-the-literal-string-undefined.md.
  • The g and u flags are accepted and ignored (issues/stddoc-str-regex-g-and-u-flags-are-silently-ignored.md), so new_with_flags(p, "g") reads as if it changed replace and does not.
  • i folds ASCII only, so an i pattern does not match É with é.

Each fix changes behaviour, so none of them is additive, and the module cannot freeze before they are decided. What IS settled: Regex / RegexMatch / RegexMatchIter / RegexError as the whole public surface, byte offsets everywhere, Result rather than exceptions from new, no separate captures (a RegexMatch always carries its groups), and the Pattern impl that lets a compiled regex be passed to any String search method.

Types

Regex object
Regex

Compiled regular expression backed by an NFA program.

Fields

NameTypeDescription
_programNfaProgram
_flagsRegexFlags
_patternString
_n_groupsusize
_group_namesArrayList(GroupNameEntry)

Trait Implementations

impl(Regex, ...)
new_with_flags : (Regex) fn(pattern : String, flags_str : String) -> Result(Regex, RegexError)

Compile pattern with the JavaScript-style flag string flags_str (any of g, i, m, s, u, y; an empty string for none). Reach for new(pattern) when there are no flags — which is most of the time.

Returns .Err(RegexError) for every malformed pattern or flag string — the variants are matchable, so a caller can report the exact fault and the byte offset it was found at.

Capture groups are not capped: the VM allocates 2 * (n_groups + 1) capture slots per NFA thread, bounded only by memory. Only the syntax is limited — \1\9 backreferences and $1$9 replacement references are single-digit, so groups past 9 are reachable by name ((?<x>…) / \k<x> / ${x}) or by RegexMatch.group(i).

Parameters

NameTypeNotes
patternString
flags_strString

Returns: Result(Regex, RegexError)

source : (Regex) fn(self : Regex) -> String

The pattern text this Regex was compiled from, exactly as given — Rust's Regex::as_str. Useful in error messages and logs; it is the SOURCE, not a canonical form, so it round-trips through Regex.new but says nothing about the compiled program.

Parameters

NameTypeNotes
selfRegex

Returns: String

new : (Regex) fn(pattern : String) -> Result(Regex, RegexError)

Compile pattern with no flags — Rust's Regex::new, and the constructor to reach for. new_with_flags is the two-argument form.

This name used to take the flag string as a second parameter, so every flagless call had to spell Regex.new(p, "") and a sibling compile(p) existed to avoid it. One name per shape, with the common shape getting the short name, removes both.

Parameters

NameTypeNotes
patternString

Returns: Result(Regex, RegexError)

escape : (Regex) fn(s : String) -> String

Quote s so every character the pattern grammar treats specially (\ ^ $ . | ? * + ( ) [ ] { }) matches literally: each is preceded by a backslash. Bytes that are already ordinary (alphanumerics, spaces, other punctuation) and non-ASCII UTF-8 sequences pass through untouched, so Regex.new(Regex.escape(s)).unwrap().is_match(s) and round-tripping a user string through a larger pattern are both safe.

Parameters

NameTypeNotes
sString

Returns: String

_extract_substring : (Regex) fn(self : Regex, bytes : ArrayList(u8), start : usize, end_pos : usize) -> String

Parameters

NameTypeNotes
selfRegex
bytesArrayList(u8)
startusize
end_posusize

Returns: String

_find_prefix_pos : (Regex) fn(self : Regex, input_bytes : ArrayList(u8), from_byte : usize) -> usize

Parameters

NameTypeNotes
selfRegex
input_bytesArrayList(u8)
from_byteusize

Returns: usize

impl(Regex, ...)
_build_match : (Regex) fn(self : Regex, slots : ArrayList(usize), input : String) -> RegexMatch

Parameters

NameTypeNotes
selfRegex
slotsArrayList(usize)
inputString

Returns: RegexMatch

impl(Regex, ...)
_find_from : (Regex) fn(self : Regex, input : String, from_byte : usize) -> Option(RegexMatch)

The scan behind exec, generalized to a nonzero start offset — what the Pattern impl needs for index_in(haystack, from). Sticky: one anchored attempt at from_byte. Otherwise every rune boundary from from_byte on, with the same literal-prefix jump exec uses.

Parameters

NameTypeNotes
selfRegex
inputString
from_byteusize

Returns: Option(RegexMatch)

find : (Regex) fn(self : Regex, input : String) -> Option(RegexMatch)

The first match in input, or .None — Rust's Regex::find.

Rust splits this into find (the span only) and captures (the span plus its groups) because the first is cheaper. Yo's RegexMatch always carries its groups — group(i), name(n) — so there is nothing for a second method to add, and the two collapse into this one.

Parameters

NameTypeNotes
selfRegex
inputString

Returns: Option(RegexMatch)

find_all : (Regex) fn(self : Regex, input : String) -> ArrayList(RegexMatch)

Every non-overlapping match, collected — Rust's find_iter().collect(). find_iter is the lazy form and is what a for loop should use.

Parameters

NameTypeNotes
selfRegex
inputString

Returns: ArrayList(RegexMatch)

impl(Regex, ...)
find_iter : (Regex) fn(self : Regex, input : String) -> RegexMatchIter

Lazy variant of find_all: returns a RegexMatchIter (an Iterator) yielding the same non-overlapping matches one at a time. Works with for m in re.find_iter(s) and with manual next() loops; see the type's doc for the advance rules.

Parameters

NameTypeNotes
selfRegex
inputString

Returns: RegexMatchIter

impl(Regex, ...)
is_match : (Regex) fn(self : Regex, input : String) -> bool

True when input contains a match — Rust's Regex::is_match.

There is no search() -> Option(usize) companion any more: it returned the first match's byte offset, which is find(input)'s RegexMatch.index(), so it was a strictly-less-informative duplicate carrying a JavaScript name.

Parameters

NameTypeNotes
selfRegex
inputString

Returns: bool

impl(Regex, ...)
_apply_replacement : (Regex) fn(self : Regex, replacement : String, m : RegexMatch) -> String

Parameters

NameTypeNotes
selfRegex
replacementString
mRegexMatch

Returns: String

impl(Regex, ...)
replace : (Regex) fn(self : Regex, input : String, replacement : String) -> String

input with the FIRST match replaced — Rust's Regex::replace.

FIRST, not all. This is deliberate and it is the one asymmetry in the whole replace family: String.replace(re, rep) — the same regex reached through the Pattern trait — replaces EVERY match (D10), because that is what str::replace means, while Regex::replace / Regex::replace_all is the split Rust's regex crate draws. So

re.replace(`aaa`, `X`)        // "Xaa"  — this method
`aaa`.replace(re, `X`)        // "XXX"  — String.replace, D10
re.replace_all(`aaa`, `X`)    // "XXX"  — say it explicitly

Returns input unchanged when nothing matches. replacement is interpreted: $& is the whole match, $1$9 are groups, ${name} is a named group, $` and $' are the text before and after the match, and $$ is a literal $. Use replace_with when the replacement has to be computed, or when the text must be inserted verbatim.

The g flag does NOT change this — the engine ignores g entirely; the method name is the only thing that decides one-or-all.

Parameters

NameTypeNotes
selfRegex
inputString
replacementString

Returns: String

replace_all : (Regex) fn(self : Regex, input : String, replacement : String) -> String

input with EVERY non-overlapping match replaced — Rust's Regex::replace_all, and the method to reach for when "replace" means all of them (replace here does the first only).

Matches come from find_all, so they are the same non-overlapping, left-to-right set, and a zero-width-matching pattern advances the way find_all advances rather than looping. replacement gets the same $ interpretation as replace. Returns input unchanged when nothing matches.

Builds the whole result in one pass over input, so it is O(input + output) rather than one string allocation per match.

Parameters

NameTypeNotes
selfRegex
inputString
replacementString

Returns: String

replace_with : (Regex) fn(self : Regex, input : String, f : Impl : (Fn(RegexMatch) -> String)) -> String

replace with the replacement COMPUTED per match: f receives the RegexMatch (so group(i)/named_group(...) are available) and returns the text to splice in. The callback IS the interpretation layer — its output is inserted verbatim, with no $1 reference processing.

Parameters

NameTypeNotes
selfRegex
inputString
fImpl : (Fn(RegexMatch) -> String)

Returns: String

replace_all_with : (Regex) fn(self : Regex, input : String, f : Impl : (Fn(RegexMatch) -> String)) -> String

replace_all with the replacement computed per match by f — same non-overlapping-match walk as replace_all, same verbatim insertion rule as replace_with.

Parameters

NameTypeNotes
selfRegex
inputString
fImpl : (Fn(RegexMatch) -> String)

Returns: String

split : (Regex) fn(self : Regex, input : String) -> ArrayList(String)

input cut at every non-overlapping match, JavaScript-style — and JavaScript-style is a real divergence from Rust worth reading twice.

Two things follow String.prototype.split(regexp) rather than Rust's Regex::split:

  • Capture groups are INTERLEAVED into the result. After each piece, the text of every group the pattern declared is pushed too, so Regex.new("(-)").unwrap().split("a-b-c") is ["a", "-", "b", "-", "c"], not ["a", "b", "c"]. A pattern with no groups behaves as you would expect.
  • A group that did not participate contributes the literal string "undefined", JavaScript's undefined rendered as text. So Regex.new(",(x)?").unwrap().split("a,b") is ["a", "undefined", "b"]. That is a magic string in a typed API and it is filed as issues/stddoc-str-regex-split-emits-the-literal-string-undefined.md; an ArrayList(Option(String)) or simply omitting non-participating groups would both be better, and both are breaking.

A pattern that never matches yields [input] — one piece, never an empty list. This is also the body behind String.split(re), so the Pattern dispatch inherits both behaviours.

Parameters

NameTypeNotes
selfRegex
inputString

Returns: ArrayList(String)

impl(Regex, Pattern(...))
is_prefix_of : (Regex) fn(self : Regex, haystack : String, position : usize) -> bool

BYTE offset in haystack to test the prefix at.

Parameters

NameTypeNotes
selfRegex
haystackString
positionusize

Returns: bool

is_suffix_of : (Regex) fn(self : Regex, haystack : String, end_position : usize) -> bool

A match must END exactly at end_position (clamped to len()).

Parameters

NameTypeNotes
selfRegex
haystackString
end_positionusize

Returns: bool

index_in : (Regex) fn(self : Regex, haystack : String, from_index : usize) -> Option(usize)

BYTE offset in AND out: searches from byte from_index, answers with the byte offset of the match.

Parameters

NameTypeNotes
selfRegex
haystackString
from_indexusize

Returns: Option(usize)

is_contained_in : (Regex) fn(self : Regex, haystack : String, from_index : usize) -> bool

BYTE offset in haystack to start searching from.

Parameters

NameTypeNotes
selfRegex
haystackString
from_indexusize

Returns: bool

last_index_in : (Regex) fn(self : Regex, haystack : String, from_index : usize) -> Option(usize)

BYTE offset in AND out: the highest byte offset a match may start at, answering with the byte offset of the last such match.

Parameters

NameTypeNotes
selfRegex
haystackString
from_indexusize

Returns: Option(usize)

length_in : (Regex) fn(self : Regex, haystack : String, at : usize) -> usize

Number of BYTES the match STARTING EXACTLY at byte offset at occupies — 0 when no match starts there. replace, replace_all, split_once and strip_prefix cut the haystack by it; a zero-width pattern (empty string, empty-matching regex) legitimately answers 0.

Parameters

NameTypeNotes
selfRegex
haystackString
atusize

Returns: usize

split_of : (Regex) fn(self : Regex, haystack : String) -> ArrayList(String)

Every piece of haystack between occurrences of this pattern, in order. The only Pattern method with no offset argument — it always covers the whole haystack — and the only one an implementation may give a shape of its own: String / str treat an EMPTY pattern as "split into runes" (see String.split), which no offset-based method can express.

Parameters

NameTypeNotes
selfRegex
haystackString

Returns: ArrayList(String)

RegexMatch object
RegexMatch

A single regex match result.

Fields

NameTypeDescription
_valueString
_indexusize
_endusize
_inputString
_groupsArrayList(Option(String))
_group_spansArrayList(Option(Range(usize)))
_group_namesArrayList(GroupNameEntry)
Methods
new : (RegexMatch) fn(value : String, index : usize, end : usize, input : String, groups : ArrayList(Option(String)), group_spans : ArrayList(Option(Range(usize))), group_names : ArrayList(GroupNameEntry)) -> RegexMatch

Compile pattern with no flags — Rust's Regex::new, and the constructor to reach for. new_with_flags is the two-argument form.

This name used to take the flag string as a second parameter, so every flagless call had to spell Regex.new(p, "") and a sibling compile(p) existed to avoid it. One name per shape, with the common shape getting the short name, removes both.

Parameters

NameTypeNotes
valueString
indexusize
endusize
inputString
groupsArrayList(Option(String))
group_spansArrayList(Option(Range(usize)))
group_namesArrayList(GroupNameEntry)

Returns: RegexMatch

value : (RegexMatch) fn(self : RegexMatch) -> String

The matched text itself — the same bytes as input().substring(index(), end()), captured at match time.

Parameters

NameTypeNotes
selfRegexMatch

Returns: String

index : (RegexMatch) fn(self : RegexMatch) -> usize

Start position of the match as a byte offset into the input.

Basis change (D4, 2026-08-26): this used to be a character (rune) index; it is now a byte index, matching String's byte-indexed API. The offset is always on a UTF-8 character boundary (a valid pattern cannot match at a continuation byte), so it can be fed directly to String.substring / index_of on the input. Use input().substring(usize(0), m.index()).chars().count() if a rune count is really needed.

Parameters

NameTypeNotes
selfRegexMatch

Returns: usize

end : (RegexMatch) fn(self : RegexMatch) -> usize

End position of the match as a byte offset into the input (exclusive — the offset of the first byte AFTER the match). Always on a UTF-8 character boundary, for the same reason as index(). span() is index() .. end().

Parameters

NameTypeNotes
selfRegexMatch

Returns: usize

span : (RegexMatch) fn(self : RegexMatch) -> Range(usize)

The whole match as a byte range index() .. end() into the input.

Parameters

NameTypeNotes
selfRegexMatch

Returns: Range(usize)

input : (RegexMatch) fn(self : RegexMatch) -> String

The whole string the match was found in, not just the matched part. The match holds a reference to it, so the offsets index() / end() / span() / group_span() stay meaningful for as long as the match does.

Parameters

NameTypeNotes
selfRegexMatch

Returns: String

group : (RegexMatch) fn(self : RegexMatch, idx : usize) -> Option(String)

The text of capture group idx, 1-based, with 0 meaning the whole match — the same numbering $1 and \1 use in patterns.

.None means EITHER that the group did not participate in this match (an unmatched (x)?, or an alternative that was not taken) OR that idx is past group_count(). The two are not distinguishable here; compare idx against group_count() first if that matters.

Parameters

NameTypeNotes
selfRegexMatch
idxusize

Returns: Option(String)

group_span : (RegexMatch) fn(self : RegexMatch, idx : usize) -> Option(Range(usize))

Capture group's byte range into the input (1-based, mirroring group(); group 0 is the full match's span()), or .None when the group did not participate in the match or the index is out of range. A participating group's range satisfies input().substring(r.start, r.end) == group(idx).unwrap().

Parameters

NameTypeNotes
selfRegexMatch
idxusize

Returns: Option(Range(usize))

named_group : (RegexMatch) fn(self : RegexMatch, name : String) -> Option(String)

The text of the group declared as (?<name>...), or .None when no group has that name OR the named group did not participate — the same conflation as group.

O(number of named groups): the name table is scanned linearly on every call, so a loop over many names over a long input is quadratic. Names are compared for exact equality, case-sensitively.

Parameters

NameTypeNotes
selfRegexMatch
nameString

Returns: Option(String)

group_count : (RegexMatch) fn(self : RegexMatch) -> usize

How many capture groups the PATTERN declared, not counting group 0 and not counting how many actually participated. So a non-participating group is still counted, and group(i) is a legal call for every 1 <= i <= group_count().

Parameters

NameTypeNotes
selfRegexMatch

Returns: usize

RegexMatchIter

Lazy iterator over a regex's non-overlapping matches — what Regex.find_iter returns. Yields exactly what find_all collects, one match at a time: next() runs the VM from the end of the previous match (an empty match advances one UTF-8 character, mirroring find_all's infinite-loop guard), so a large input can be scanned without materializing every match. Single-pass: once next() returns .None the iterator is exhausted (it does not rewind).

Fields

NameTypeDescription
_regexRegex
_vmNfaVm
_inputString
_byte_posusize
_has_prefixbool

Trait Implementations

impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
into_iter : fn(self : I : (Iterator)) -> I

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: I : (Iterator)

impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> B)) -> IterMap(I : (Iterator), B, F : (Fn(A) -> B))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> B)

Returns: IterMap(I : (Iterator), B, F : (Fn(A) -> B))

filter : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterFilter(I : (Iterator), F : (Fn(A) -> bool))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> bool)

Returns: IterFilter(I : (Iterator), F : (Fn(A) -> bool))

take : fn(generic(A) self : I : (Iterator), n : usize) -> IterTake(I : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
nusize

Returns: IterTake(I : (Iterator))

skip : fn(generic(A) self : I : (Iterator), n : usize) -> IterSkip(I : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
nusize

Returns: IterSkip(I : (Iterator))

enumerate : fn(generic(A) self : I : (Iterator)) -> IterEnumerate(I : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: IterEnumerate(I : (Iterator))

zip : fn(generic(A, J, B) self : I : (Iterator), other : J : (Iterator)) -> IterZip(I : (Iterator), J : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
otherJ : (Iterator)

Returns: IterZip(I : (Iterator), J : (Iterator))

fold : fn(generic(A, Acc, F) self : I : (Iterator), init : Acc, f : F : (Fn(Acc, A) -> Acc)) -> Acc

Parameters

NameTypeNotes
selfI : (Iterator)
initAcc
fF : (Fn(Acc, A) -> Acc)

Returns: Acc

for_each : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> unit)) -> unit

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> unit)

Returns: unit

count : fn(generic(A) self : I : (Iterator)) -> usize

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: usize

any : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> bool

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: bool

all : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> bool

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: bool

find : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(A)

The first match in input, or .None — Rust's Regex::find.

Rust splits this into find (the span only) and captures (the span plus its groups) because the first is cheaper. Yo's RegexMatch always carries its groups — group(i), name(n) — so there is nothing for a second method to add, and the two collapse into this one.

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: Option(A)

position : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(usize)

Parameters

NameTypeNotes
selfI : (Iterator)
predF : (Fn(A) -> bool)

Returns: Option(usize)

last : fn(generic(A) self : I : (Iterator)) -> Option(A)

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: Option(A)

nth : fn(generic(A) self : I : (Iterator), n : usize) -> Option(A)

Parameters

NameTypeNotes
selfI : (Iterator)
nusize

Returns: Option(A)

sum : fn(generic(A) self : I : (Iterator)) -> A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)

min : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

max : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))

chain : fn(generic(A, J) self : I : (Iterator), other : J : (Iterator)) -> IterChain(I : (Iterator), J : (Iterator))

Parameters

NameTypeNotes
selfI : (Iterator)
otherJ : (Iterator)

Returns: IterChain(I : (Iterator), J : (Iterator))

take_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> bool)

Returns: IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))

skip_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> bool)

Returns: IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))

filter_map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> Option(B))) -> IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))

Parameters

NameTypeNotes
selfI : (Iterator)
fF : (Fn(A) -> Option(B))

Returns: IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))

peekable : fn(generic(A) self : I : (Iterator)) -> IterPeekable(I : (Iterator), A)

Parameters

NameTypeNotes
selfI : (Iterator)

Returns: IterPeekable(I : (Iterator), A)

collect : fn(self : I : (Iterator), C : Type) -> C : (FromIterator)

Parameters

NameTypeNotes
selfI : (Iterator)
CTypecomptime

Returns: C : (FromIterator)

impl(RegexMatchIter, Iterator(...))
Item : RegexMatch
next : (RegexMatchIter) fn(self : RegexMatchIter) -> Option(RegexMatch)

Advance the iterator and return the next value, or None when exhausted.

Parameters

NameTypeNotes
selfRegexMatchIter

Returns: Option(RegexMatch)

RegexError enum
RegexError

Everything Regex.new can reject, split by what the user has to fix.

Variants

VariantFieldsDescription
UnexpectedEndpos: usize

The pattern ended where an expression was expected, e.g. a| inside a {m,n} quantifier or after an operator.

TrailingBackslashpos: usize

The pattern ends with a \ that escapes nothing.

UnterminatedCharClasspos: usize

A [ character class was never closed with ].

UnterminatedGrouppos: usize

A ( group was never closed with ).

UnmatchedCloseParenpos: usize

A ) appeared with no ( to close.

InvalidQuantifierpos: usize

A {m,n} quantifier is malformed — a missing bound, or a missing ,/}.

QuantifierOutOfOrdermin: usize, max: usize, pos: usize

A {m,n} quantifier whose upper bound is below its lower bound.

InvalidBackreferencegroup: usize, pos: usize

\1\9 naming a group the pattern does not have.

InvalidNamedBackreferencepos: usize

\k not followed by <name>, or a \k<name that is never closed.

UnknownGroupNamename: String, pos: usize

\k<name> naming a group the pattern does not define.

InvalidUnicodePropertypos: usize

\p / \P not followed by {name}, or a \p{name that is never closed.

UnknownUnicodePropertyname: String, pos: usize

\p{name} / \P{name} naming a property this engine does not know.

InvalidFlagflag: u8

A flag character outside gimsuy.

DuplicateFlagflag: u8

The same flag character given more than once.

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
to_string : (RegexError) fn(self : RegexError) -> String

Parameters

NameTypeNotes
selfRegexError

Returns: String

source : (RegexError) fn(self : RegexError) -> Option(dyn( + ToString))

The pattern text this Regex was compiled from, exactly as given — Rust's Regex::as_str. Useful in error messages and logs; it is the SOURCE, not a canonical form, so it round-trips through Regex.new but says nothing about the compiled program.

Parameters

NameTypeNotes
selfRegexError

Returns: Option(dyn( + ToString))