Skip to content

std.regex

linear-time Pike VM; UTF-8 runes, byte offsets, leftmost-first not thread-safe: one thread per Regex; a Match is valid until the next search

pub RegexError :: errors {
unclosed_group,
unmatched_paren,
bad_class,
bad_escape,
nothing_to_repeat,
bad_count,
too_big,
}
  • unclosed_group: a ( without its )
  • unmatched_paren: a ) without its (
  • bad_class: unclosed [, or a backwards range ([z-a])
  • bad_escape: unknown escape letter or digit
  • nothing_to_repeat: *, +, ? or { with nothing before it
  • bad_count: {n,m} with m < n, or more than 1000
  • too_big: a program past 50000 instructions
pub Regex :: struct {
prog: []Inst,
ranges: []Range,
classes: []ClassRef,
names: []const []const u8,
ncap: usize,
multiline: bool,
clist: []u32,
nlist: []u32,
ccaps: []usize,
ncaps: []usize,
mark: []u32,
gen: u32,
stack: []u64,
work: []usize,
result: []usize,
region: *Arena,
}

compiled pattern plus its match memory; one thread at a time

  • ncap: 2 slots per group; group 0 = whole match
  • ccaps: a thread at slot k has its captures at k * ncap
  • mark: the generation a pc was last added in
  • stack: pc << 1, or restore: slot << 33 | old << 1 | 1
  • work: the captures being followed
  • result: the last match’s captures
pub is_match :: fn(self: *Self, text: []const u8) -> bool

match anywhere

pub find :: fn(self: *Self, text: []const u8) -> ?Match

leftmost match, or null

pub find_at :: fn(self: *Self, text: []const u8, start: usize) -> ?Match

leftmost match starting at or after start

pub find_all :: fn(self: *Self, text: []const u8) -> Matches

non-overlapping matches, left to right

pub group_count :: fn(self: *Self) -> usize

capture groups, not counting group 0

pub group_index :: fn(self: *Self, name: []const u8) -> ?usize

number of the group name, or null

pub replace_all :: fn(self: *Self, a: *Arena, text: []const u8, with: []const u8) -> []const u8

result in a; $0 match, $1 / ${1} / ${name} group, $$ a $

pub split :: fn(self: *Self, a: *Arena, text: []const u8) -> []const []const u8

pieces between matches, in a

pub Span :: struct {
start: usize,
end: usize,
}

byte offsets

pub Match :: struct {
re: *Regex,
text: []const u8,
}

valid until the next search with its Regex

pub start :: fn(self: *Self) -> usize
pub end :: fn(self: *Self) -> usize
pub str :: fn(self: *Self) -> []const u8

whole match

pub group :: fn(self: *Self, i: usize) -> ?[]const u8

group i (0 = whole match); null if it took no part

pub span :: fn(self: *Self, i: usize) -> ?Span

byte offsets of group i; null if it took no part

pub named :: fn(self: *Self, name: []const u8) -> ?[]const u8

group name, or null

pub Matches :: struct {
re: *Regex,
text: []const u8,
pos: usize,
last_empty: bool,
done: bool,
}

non-overlapping; an empty match right after another is ok, two at one place aren’t

pub next :: fn(self: *Self) -> ?Match
pub compile :: fn(a: *Arena, pattern: []const u8) -> Regex ! RegexError

working memory in a