Skip to content
Kavachकवच

Regex

● Intermediate5 minBefore this: StringsSpec 14.8

A regular expression is a pattern that text can match. regex.new makes one; its methods find, capture, replace and split.

use std.regex

fn main() ! Error {
    const email = try regex.new(r"^[\w.+-]+@[\w-]+\.[\w.]+$")
    print(email.is_match("asha@example.com"))
    print(email.is_match("asha at example"))

    const date = try regex.new(r"(?<year>\d{4})-(?<month>\d{2})")
    const parts = date.named_captures("due 2026-10") ?? [:]
    print(parts["year"] ?? "")
    print(parts["month"] ?? "")
}

The program ran and printed:

kavach run match.kav

truefalse202610
match.kav: Kavach code, then what running it prints
  • Write patterns as raw strings, r"…", so \d needs no extra backslash.
  • (?<year>…) is a named group; named_captures gives each one by name.

Find, split, replace

use std.regex

fn main() ! Error {
    const number = try regex.new(r"\d+")
    print(number.find("order 42 of 7") ?? "none")
    print(number.find_all("order 42 of 7, room 301"))
    const spaces = try regex.new(r"\s*,\s*")
    print(spaces.split("mango , fig,  tea"))
}

The program ran and printed:

kavach run find.kav

42["42", "7", "301"]["mango", "fig", "tea"]
find.kav: Kavach code, then what running it prints
use std.regex

fn main() ! Error {
    const date = try regex.new(r"(?<day>\d{2})/(?<month>\d{2})/(?<year>\d{4})")
    print(date.replace_all("from 03/11/2026 to 10/11/2026", r"${year}-${month}-${day}"))
    const card = try regex.new(r"\d{4} \d{4} \d{4} (\d{4})")
    print(card.replace("card 4242 4242 4242 1881", r"**** **** **** $1"))
}

The program ran and printed:

kavach run replace.kav

from 2026-11-03 to 2026-11-10card **** **** **** 1881
replace.kav: Kavach code, then what running it prints

In the replacement, ${year} and $1 insert a group: a raw string keeps {…} from being read as interpolation.

A pattern that is wrong

use std.regex

fn main() {
    const pattern = regex.new(r"(\d+") catch e => {
        print("bad pattern: {e}")
        return
    }
    print(pattern)
}

The program ran and printed:

kavach run bad.kav

bad pattern: invalid pattern `(\d+`: unclosed group
bad.kav: Kavach code, then what running it prints

Every method

MethodGives
is_match(text)Whether the pattern matches anywhere in text
find(text)The first match, or none
find_all(text)Every match that doesn't overlap the one before
captures(text)For the first match: the whole match then each group, none for a group that didn't take part; or none without a match
named_captures(text)For the first match: each named group that took part, by name; or none
replace(text, with), replace_all(text, with)The text with the first or every match replaced; in with, $1 and ${name} insert a group (write with as a raw string, r"${name}", so {…} is not interpolation)
split(text)The parts of text between matches

regex.new matches in time proportional to the text, whatever the pattern, so text from users can't make it hang. regex.advanced also allows lookaround and backreferences, and gives up after a fixed amount of work.