Skip to content

stdlib.regex

Regular Expressions

Generated from v0.65.7. 4 source files, 56 documented symbols.

engine.xi

type Regex

A compiled regular expression: the validated pattern text and a handle. compiled is reserved for future native backends and is always 0 here.

Field Type
pattern Str
compiled Int

Derives: Clone

type Match

A match: half-open byte range [start, end) and the matched text.

Field Type
start Int
end Int
text Str

Derives: Eq, Clone

fn regex_compile(pattern: Str) -> Result[Regex, Str]

Compile a regex pattern. Validates the syntax and returns a compiled Regex, or Err describing the problem on invalid syntax. Complexity: O(len(pattern)) validation.

  • Postcondition: (is_valid_regex(pattern)) => (result is Ok(_))
  • Postcondition: (!is_valid_regex(pattern)) => (result is Err(_))
fn regex_match(r: Regex, s: Str) -> Bool

True when r matches the entire string s (anchored at both ends). Complexity: O(len(s) * len(r)) worst case for the backtracking matcher.

  • Precondition: r.compiled == 0
fn regex_find(r: Regex, s: Str) -> Option[Match]

Find the first match of r in s, or None when there is no match. Complexity: O(len(s) * len(r)) worst case.

  • Precondition: r.compiled == 0
fn regex_find_all(r: Regex, s: Str) -> Vec[Match]

Find every non-overlapping match of r in s, in left-to-right order. An empty pattern matches at every byte boundary. Complexity: O(len(s) * len(r)) per match.

  • Precondition: r.compiled == 0
  • Postcondition: (r.pattern.len() == 0) => (result.len() == s.len() + 1)
fn regex_captures(r: Regex, s: Str) -> Option[Vec[Str]]

Capture groups of the first match of r in s. This engine has no group syntax, so the returned vector contains exactly one element: the full match text (group 0). None when there is no match. Complexity: O(len(s) * len(r)) worst case.

  • Precondition: r.compiled == 0
fn regex_capture_names(r: Regex) -> Vec[Str]

Names of the named capture groups. This engine has no named-group syntax, so the result is always an empty vector. Complexity: O(1).

  • Postcondition: result.len() == 0
fn regex_is_match(pattern: Str, s: Str) -> Bool

Convenience: compile pattern then search s for any match (find semantics, like PCRE pcre_exec). Returns false on invalid pattern syntax or when there is no match. Complexity: O(len(s) * len(pattern)) worst case.

  • Postcondition: (!is_valid_regex(pattern)) => (result == false)
fn regex_matches(pattern: Str, s: Str) -> Vec[Match]

Convenience: compile pattern then find all matches in s. Returns an empty vector on invalid pattern syntax. Complexity: O(len(s) * len(pattern)) worst case.

  • Postcondition: (!is_valid_regex(pattern)) => (result.len() == 0)
fn regex_replace(r: Regex, s: Str, replacement: Str) -> Str

Replace the first match of r in s with replacement. Returns s unchanged when there is no match. Literal replacement (no $1). Complexity: O(len(s) + len(replacement)).

  • Precondition: r.compiled == 0
fn regex_replace_all(r: Regex, s: Str, replacement: Str) -> Str

Replace every non-overlapping match of r in s with replacement. Returns s unchanged when there are no matches. Literal replacement. Complexity: O(len(s) + matches * len(replacement)).

  • Precondition: r.compiled == 0
fn regex_split(r: Regex, s: Str) -> Vec[Str]

Split s around every non-overlapping match of r. An empty pattern splits into individual characters. The trailing segment is always present. Complexity: O(len(s) * len(r)) worst case.

  • Precondition: r.compiled == 0
  • Postcondition: result.len() >= 1
fn regex_find_iter(r: Regex, s: Str) -> Vec[Match]

Lazily-ordered iterator of every match of r in s, materialised as a vector in left-to-right order. Equivalent to regex_find_all. Complexity: O(len(s) * len(r)) worst case.

  • Precondition: r.compiled == 0
  • Postcondition: result.len() == regex_find_all(r, s).len()



pcre_lite.xi

type PcreRegistry

Internal registry of compiled patterns, keyed by handle - 1. Public so the compiler can allocate the module-level registry for imported modules.

Field Type
patterns Vec[Str]
fn pcre_compile(pattern: Str, flags: Int) -> Result[Int, Str]

Compile pattern to an integer handle, or Err on invalid syntax. flags is reserved for future PCRE options and is currently ignored (documented: only flags == 0 is honoured). Complexity: O(len(pattern)).

  • Postcondition: (syntax.regex_validate(pattern)) => (result is Ok(_))
  • Postcondition: (!syntax.regex_validate(pattern)) => (result is Err(_))
fn pcre_match(compiled: Int, s: Str) -> Bool

True when the compiled pattern compiled matches somewhere in s (search semantics, not whole-string). False for invalid handles. Complexity: O(len(s) * len(pattern)) worst case.

  • Postcondition: (pattern_for(compiled) is None) => (result == false)
fn pcre_exec(compiled: Int, s: Str) -> Vec[Int]

Every match of the compiled pattern compiled in s as flattened (start, end) byte-index pairs: [s0, e0, s1, e1, ...]. Empty for invalid handles or no matches. Complexity: O(len(s) * len(pattern)) worst case.

  • Postcondition: (pattern_for(compiled) is None) => (result.len() == 0)
  • Postcondition: (pattern_for(compiled) is Some(_)) => (result.len() % 2 == 0)
fn pcre_replace(compiled: Int, s: Str, replacement: Str) -> Str

Replace the first match of the compiled pattern compiled in s with replacement. Returns s unchanged for invalid handles. Complexity: O(len(s) + len(replacement)).

  • Postcondition: (pattern_for(compiled) is None) => (result == s)
fn pcre_split(compiled: Int, s: Str) -> Vec[Str]

Split s around every match of the compiled pattern compiled. Returns [s] (a single segment) for invalid handles. Complexity: O(len(s) * len(pattern)) worst case.

  • Postcondition: (pattern_for(compiled) is None) => (result.len() == 1 && result[0] == s)
  • Postcondition: (pattern_for(compiled) is Some(_)) => (result.len() >= 1)
fn pcre_free(compiled: Int)

Release the resources of a compiled handle. The registry keeps patterns alive for the whole process, so this is a documented no-op. Complexity: O(1).

  • Precondition: true
fn pcre_version() -> Str

Version string of this embedded PCRE implementation. Complexity: O(1).

  • Postcondition: result.len() > 0
fn pcre_capture_count(compiled: Int) -> Int

Number of capture groups in the compiled pattern. The engine has no group syntax, so this is always 0 for valid handles; invalid handles also return 0. Complexity: O(1).

  • Postcondition: result == 0



regex.xi

type Regex

Compiled regular expression (wraps the pattern string).

Field Type
pattern Str
compiled Int

Derives: Clone

type Match

A matched span of the input.

Field Type
start Int
end Int
text Str

Derives: Eq, Clone

type Captures

Capture groups of the first match; None for unmatched groups.

Field Type
groups Vec[Option[Match]]

Derives: Clone

fn new(pattern: Str) -> Result[Regex, Str]

Compile a pattern; Err with a message on syntax errors.

  • Postcondition: pattern.len() == 0 => result is Ok(_)

fn is_match(self: Self, text: Str) -> Bool

True when the pattern matches anywhere in text.

  • Postcondition: self.pattern.len() == 0 => result == true

fn find(self: Self, text: Str) -> Option[Match]

First match in text, or None.

  • Postcondition: result.is_some => result.value.start >= 0 && result.value.end >= result.value.start
  • Postcondition: result.is_some => result.value.end <= text.len()

fn find_all(self: Self, text: Str) -> Vec[Match]

All non-overlapping matches in text.

  • Postcondition: result.len() <= text.len() + 1
  • Postcondition: self.pattern.len() == 0 => result.len() == text.len() + 1

fn captures(self: Self, text: Str) -> Option[Captures]

Capture groups of the first match, or None.

  • Postcondition: result is Some(_) => result.value.groups.len() == 1

fn replace(self: Self, text: Str, replacement: Str) -> Str

Replace the first match with replacement.

  • Postcondition: result.len() <= text.len() + replacement.len()

fn replace_all(self: Self, text: Str, replacement: Str) -> Str

Replace all non-overlapping matches.

  • Postcondition: result.len() <= text.len() + (text.len() + 1) * replacement.len()
  • Postcondition: self.pattern.len() == 0 => result.len() == text.len() + (text.len() + 1) * replacement.len()

fn split(self: Self, text: Str) -> Vec[Str]

Split text on matches of the pattern.

  • Postcondition: self.pattern.len() > 0 => result.len() >= 1
  • Postcondition: result.len() <= text.len() + 2

fn match_count(self: Self, text: Str) -> Int

Number of non-overlapping matches.

  • Postcondition: result >= 0 && result <= text.len() + 1

fn get(self: Self, index: Int) -> Option[Match]

Group at index (0 = whole match), or None when absent.

  • Postcondition: result is Some(_) => index >= 0 && index < self.groups.len()
  • Postcondition: result is None => index < 0 || index >= self.groups.len()

fn get_named(self: Self, name: Str) -> Option[Match]

Named group by name, or None when absent.

  • Postcondition: result is None

fn len(self: Self) -> Int

Number of capture groups including the whole match.

  • Postcondition: result == self.groups.len()

fn regex_escape(pattern: Str) -> Str

Escape regex metacharacters so the result matches literally.

  • Postcondition: result.len() >= pattern.len() && result.len() <= 2 * pattern.len()

fn is_valid_regex(pattern: Str) -> Bool

True when the pattern compiles.

  • Postcondition: pattern.len() == 0 => result == true

fn regex_replace_all(re: Regex, text: Str, replacement: Str) -> Str

Replaces all non-overlapping matches of re in text with replacement. Uses literal replacement (no $1 group references).

  • Postcondition: result.len() <= text.len() + (text.len() + 1) * replacement.len()
  • Postcondition: re.pattern.len() == 0 => result.len() == text.len() + (text.len() + 1) * replacement.len()

fn regex_find_first_str(re: Regex, text: Str) -> Option[Str]

Finds the first match of re in text and returns the matched substring. Returns None if no match is found.

  • Postcondition: result is Some(_) => result.value.len() <= text.len()
  • Postcondition: re.pattern.len() == 0 => result is Some(_)

fn regex_split(re: Regex, text: Str) -> Vec[Str]

Splits text around all non-overlapping matches of re. Returns a Vec of substrings between matches.

  • Postcondition: re.pattern.len() > 0 => result.len() >= 1

fn regex_count_matches(re: Regex, text: Str) -> Int

Returns the number of non-overlapping matches of re in text.

  • Postcondition: result >= 0 && result <= text.len() + 1

fn regex_matches_all(re: Regex, text: Str) -> Vec[Match]

Returns all non-overlapping matches of re in text as Match objects. Wraps Regex.find_all.

  • Postcondition: result.len() <= text.len() + 1

fn regex_extract_groups(re: Regex, text: Str) -> Vec[Option[Str]]

Extracts capture groups from the first match of re in text. Returns a Vec where each element is the text of a captured group, or None if that group did not participate in the match. The first element (index 0) is the full match.

  • Postcondition: result.len() <= 1

fn regex_escape_literal(s: Str) -> Str

Escapes regex metacharacters in s so it can be used as a literal pattern. Wraps regex_escape.

  • Postcondition: result.len() >= s.len() && result.len() <= 2 * s.len()

fn regex_is_valid(pattern: Str) -> Bool

Returns true if pattern is a syntactically valid regex. Checks for balanced brackets and valid quantifier positions. Wraps is_valid_regex.

  • Postcondition: pattern.len() == 0 => result == true


syntax.xi

type Ast

A summary syntax tree for a validated pattern. node_count is the number of pattern elements, group_count the number of (...) groups and class_count the number of character classes. This engine supports no groups, so group_count is always 0 for valid patterns.

Field Type
pattern Str
node_count Int
group_count Int
class_count Int

Derives: Clone

fn regex_escape(s: Str) -> Str

Escape every metacharacter in s so the text matches literally. Complexity: O(len(s)).

  • Postcondition: result.len() >= s.len() && result.len() <= 2 * s.len()
fn regex_unescape(s: Str) -> Result[Str, Str]

Decode escape sequences back to plain text. Handles escaped metacharacters (\*, \\, \[, ...) and the standard control escapes \n, \t, \r. Any other \x sequence decodes to the literal character x. A trailing backslash is an error. Complexity: O(len(s)).

  • Postcondition: result is Ok(_) => result.value.len() <= s.len()
fn regex_parse(pattern: Str) -> Result[Ast, Str]

Parse pattern into a summary Ast, or Err when the syntax is invalid. The AST counts pattern elements, groups and character classes. Complexity: O(len(pattern)).

  • Postcondition: result is Err(_) => pattern.len() > 0
  • Postcondition: result is Ok(_) => result.value.pattern == pattern
fn regex_validate(pattern: Str) -> Bool

True when pattern is syntactically valid (balanced classes, no dangling escape or leading quantifier). Complexity: O(len(pattern)).

  • Postcondition: pattern.len() == 0 => result == true
fn regex_syntax_error(pattern: Str) -> Option[Str]

The first syntax error message for pattern, or None when it is valid. Complexity: O(len(pattern)).

  • Postcondition: pattern.len() == 0 => result is None
fn regex_character_class(name: Str) -> Str

Pattern text for a named character class. Supported names: alpha, digit, space, alnum, upper, lower, word, xdigit, punct, graph, print, any. Unknown names return the empty string. Complexity: O(1).

  • Postcondition: name.len() == 0 => result.len() == 0
  • Postcondition: result.len() <= 14
fn regex_quantifier(min: Int, max: Int) -> Str

Build the pattern text for a {min,max} quantifier. When max == min the shorthand {min} is emitted, when max < 0 the open form {min,} is emitted. Invalid ranges (max >= 0 and max < min, or min < 0) return "". Complexity: O(1).

  • Postcondition: min < 0 => result.len() == 0
  • Postcondition: max >= 0 && max < min => result.len() == 0
  • Postcondition: min >= 0 && (max < 0 || max >= min) => result.len() >= 3