RatMinimal web framework

Regex

The regex namespace has four members. Patterns use Go's RE2 syntax: no backrefs or lookaround, but linear-time evaluation is guaranteed. Compiled patterns are cached, so reusing the same pattern across many calls compiles only once. $1-style backrefs in replacements work the same on the server and in the browser.

regex.match: first hit only

Returns a match object or null

regex.match(pattern, s) returns the first match as an object with fields match (the matched substring), groups (capture groups in order), start, and end (byte offsets). On no match it returns null, so handler code branches with (m is not null) before reading fields.

<p> [regex.match('\\d+', 'abc 123 xyz')]
Result

{match: 123, groups: [], start: 4, end: 7}

regex.find_all: every hit

Array of match objects

regex.find_all(pattern, s) returns every non-overlapping match in an array. Each element has the same shape as the single-match form.

<p> [regex.find_all('\\d+', '1 two 3 four 55')]
Result

[{match: 1, groups: [], start: 0, end: 1}, {match: 3, groups: [], start: 6, end: 7}, {match: 55, groups: [], start: 13, end: 15}]

regex.replace: all occurrences, with backrefs

$1, $2 reference capture groups

regex.replace(pattern, s, replacement) swaps every match. The replacement string can reference capture groups with $1, $2, etc. For a literal dollar sign in the output, double it ($$).

<p> [regex.replace('(\\w+)=(\\d+)', 'a=1, b=2', '$2 of $1')]
Result

1 of a, 2 of b

regex.split: pattern as separator

Useful for runs of whitespace, mixed delimiters

regex.split(pattern, s) cuts the string wherever the pattern matches. Common case: collapsing arbitrary whitespace runs into a clean array of tokens.

<p> [regex.split('\\s+', 'one  two three')]
Result

[one, two, three]

Capture groups in find_all

groups0, groups1, etc. in pattern order

Each match object exposes its capture groups in an array, in source order. Use the array to pull out the parts of the match without re-parsing the matched substring.

> page
hits: regex.find_all('(\\w+)=(\\d+)', 'a=1, b=2, c=33')

<ul>
    [h] in hits
        <li> [h.groups[0]][h.groups[1]]

Pattern caveats

RE2: no backrefs, no lookaround

The RE2 dialect rules out a few features common in PCRE: no backreferences in patterns (\\1), no lookahead / lookbehind. The trade-off is guaranteed linear-time evaluation, so pasted patterns can never catastrophically backtrack. Backrefs in replacements ($1) are fine; the restriction is only on patterns.

See also Strings · Collections · JSON