std/regex

Regular expressions in the syntax of RE2 and Go, matched in time linear in the text: a pattern compiles to a program that a Pike VM runs over every way a match can go at once, so no pattern backtracks, and there are no backreferences. Offsets are byte offsets.

import "std/regex"

Regex date = regex("(?P<year>\\d{4})-(?P<month>\\d{2})")?
print(date.matches("due 2026-11"))                           // true
print(date.replace("2026-11 and 2027-01", "${month}/${year}"))  // 11/2026 and 01/2027
for m in date.find_all("2026-11 and 2027-01") do
    print(m.start, m.stop, m.text)
end

regex(pattern) gives a Result[Regex], an ERROR of kind "invalid_pattern" saying what is wrong and where; regex(pattern, flags: "i") sets flags as (?i) would. A pattern compiled once is kept, so compiling it again costs nothing. A Regex has these methods:

Method Result
matches(text), full_match(text) whether it matches somewhere in the text, or the whole of it
find(text), find_at(text, start) the first match, as an Option[RegexMatch] with start, stop, and text
find_all(text) every match, one after another; an empty match right after another is left out
captures(text), captures_all(text) the groups of the first match, or of every match, as Captures
captures_at(text, start) the groups of the first match that starts at byte start or later
replace(text, template), replace_first(text, template) the text with every match, or the first, replaced; $1 or ${1} is a group, ${name} a named one, $0 the match, and $$ a $
replace_with(text, make) every match replaced by what a function gives for its Captures
split(text) the pieces between the matches
matches_bytes(data), find_bytes(data), find_all_bytes(data) the same on bytes that need not be UTF-8

Captures has group(index) and named(name), each an Option[str] that is NONE for a group that took no part, span(index), the start and end of a group, and count(). regex_escape(text) escapes what means something in a pattern.

The syntax: literals; .; classes such as [a-z], [^0-9], and [[:alpha:]]; \d, \w, and \s, of ASCII, and their capitals for the rest; \p{L}, \p{Lu}, \p{Greek}, and \p{Any} for Unicode categories and scripts, \P{...} or \p{^...} for the rest; \x41, \x{1F600}, \101, \n, \t, and \Q...\E for literal text; ^, $, \A, \z, \b, and \B; groups (...), (?:...), and (?P<name>...) or (?<name>...); |; *, +, ?, {n}, {n,}, and {n,m}, each lazy with a ? after it; and the flags i (any case, by Unicode's simple case folding), m (^ and $ at each line), s (. takes \n too), and U (repetitions lazy unless ? makes them greedy), as (?i) for the rest of the group or (?i:...) for a part. A match is leftmost, and of the alternatives that match there, the first, as Perl and RE2 choose. Repetition counts go up to 1000. In bytes, a byte that does not start a valid character matches . and the classes that leave characters out.