🔍
clib v1.0.0 Text Processing
re2
Safe, fast, thread-friendly regular expressions via Google's RE2 engine. Guarantees linear-time O(n) matching — no catastrophic backtracking, no ReDoS attacks.
Install ppm install re2
What is RE2?

RE2 is a safe regular expression engine developed by Google. Unlike PCRE or the standard std::regex, RE2 is built on finite automata (NFA/DFA) and strictly avoids backtracking. This gives it a hard O(n) time guarantee on every input, where n is the length of the text being searched.

The practical consequence: no matter how cleverly a pattern is crafted, RE2 will never hang. This makes it the correct choice for user-supplied patterns in production services — web forms, APIs, log processors, security tools — anywhere that a malicious or accidental ReDoS pattern could otherwise bring a server to its knees.

Linear time O(n) — matching time is proportional to input length only, never to pattern complexity
No ReDoS — immune to catastrophic backtracking attacks by design
Thread-safe — compiled patterns can be shared across goroutines/threads without locking
Full Unicode — UTF-8 by default, Unicode character classes (\pL, \p{Greek}), POSIX classes
Named capture groups(?P<name>...) syntax, accessible via GetNamedGroup
Used by Go standard library (regexp package), Chromium, Grafana, and Kubernetes
RE2 vs Other Engines
RE2
Time: O(n) — linear
ReDoS: impossible
Thread-safe: yes
Lookahead: no
Backref: no
PCRE2
Time: O(2^n) worst
ReDoS: possible
Thread-safe: w/ jit lock
Lookahead: yes
Backref: yes
std::regex
Time: O(2^n) worst
ReDoS: possible
Thread-safe: read-only ok
Lookahead: yes
Backref: yes
RE2 Limitations
RE2 does not support features that require backtracking: lookahead (?=...), lookbehind (?<=...), negative variants, backreferences \1, possessive quantifiers a++, or atomic groups (?>...). If you need these features and trust your inputs, consider the regex package instead.
Types
Type Underlying Description
TRE2Regex Integer Handle to a compiled RE2 pattern. Created by Compile / CompileEx. Must be freed with FreeRegex when done.
TRE2Options record Compilation flags passed to CompileEx. Fields: CaseInsensitive, Latin1, Longest, Literal, NeverNewline, DotNewline, MaxMemory.
TRE2Match record Result of a match operation. Contains Matched: Boolean, FullMatch: string, Start / Length (byte offsets), Groups: array of string (unnamed captures), and NamedGroups (Name/Value pairs).
TRE2Options Fields
FieldDescription
CaseInsensitiveCase-insensitive matching, equivalent to inline flag (?i).
Latin1Treat input text as Latin-1 instead of UTF-8.
LongestPrefer the longest match (POSIX leftmost-longest semantics).
LiteralTreat the entire pattern as a literal string, no metacharacters.
NeverNewline. never matches \n (default behavior).
DotNewline. matches \n as well (dot-all / single-line mode).
MaxMemoryMaximum DFA memory in bytes. Default 0 = 8 MB. Increase for complex patterns on very long inputs.
API Reference
Compile / Free
function Compile(Pattern: string): TRE2Regex
Compile a RE2 pattern. Returns a handle. Check with IsValid before use.
function CompileEx(Pattern: string; Opts: TRE2Options): TRE2Regex
Compile with custom options (case-insensitive, dot-all, Latin-1, etc.).
procedure FreeRegex(R: TRE2Regex)
Free a compiled pattern. Must be called once per Compile / CompileEx to avoid memory leaks.
function IsValid(R: TRE2Regex): Boolean
Returns True if the pattern compiled without errors.
function GetError(R: TRE2Regex): string
Returns the compile error message when IsValid is False.
Match
function IsMatch(R: TRE2Regex; Text: string): Boolean
Returns True if the pattern matches anywhere in Text. O(n) guaranteed. No groups returned.
function Match(R: TRE2Regex; Text: string): TRE2Match
Find the first occurrence of the pattern anywhere in Text. Returns match with capture groups.
function FullMatch(R: TRE2Regex; Text: string): TRE2Match
Pattern must match the entire string. Equivalent to anchoring with ^...$.
function PrefixMatch(R: TRE2Regex; Text: string): TRE2Match
Pattern must match at the start of the string. Equivalent to anchoring with ^....
function MatchAll(R: TRE2Regex; Text: string): array of TRE2Match
Find all non-overlapping matches in Text. Returns an array of match results, each with capture groups.
function MatchAt(R: TRE2Regex; Text: string; Offset: Integer): TRE2Match
Find a match starting at a specific byte offset in Text. Useful for iterative scanning.
Named Groups
function GetNamedGroup(MR: TRE2Match; Name: string): string
Retrieve the value of a named capture group from a match result. Returns empty string if the group did not participate.
function NamedGroups(R: TRE2Regex): array of string
List all named group names defined in the compiled pattern, in left-to-right order.
function GroupCount(R: TRE2Regex): Integer
Returns the total number of capture groups (named + unnamed) in the pattern.
Replace
function Replace(R: TRE2Regex; Text, Rewrite: string): string
Replace the first match of the pattern in Text. Rewrite may reference groups as \1, \2 or \{name}.
function ReplaceAll(R: TRE2Regex; Text, Rewrite: string): string
Replace all non-overlapping matches. Same rewrite syntax as Replace.
Split
function Split(R: TRE2Regex; Text: string; Limit: Integer): array of string
Split Text at every match of the pattern. Limit caps the number of parts; use 0 for unlimited.
One-Shot Helpers
function QuickTest(Pattern, Text: string): Boolean
Compile and test in a single call. Convenient for one-off checks; avoid in loops (recompiles each call).
function QuickMatch(Pattern, Text: string): TRE2Match
Compile, match, and return result in one call. Pattern is freed internally after the match.
function QuickReplace(Pattern, Text, Rewrite: string): string
Compile, replace-all, and return result in one call.
Pattern Info
function MinMatchLength(R: TRE2Regex): Integer
Minimum length of a string that can match the pattern. Returns 0 if the pattern can match an empty string.
function CanMatchEmpty(R: TRE2Regex): Boolean
Returns True if the pattern can match a zero-length string.
function RE2Version(): string
Returns the version string of the underlying RE2 C library, e.g. "2024-03-01".
Code Example
uses re2; var R : TRE2Regex; M : TRE2Match; All : array of TRE2Match; Opts: TRE2Options; I : Integer; begin { ── Compile a pattern with named groups ──────────────────── } R := Compile('(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'); if not IsValid(R) then begin WriteLn('Bad pattern: ', GetError(R)); Exit; end; { ── Full match — pattern must cover the entire string ─────── } M := FullMatch(R, '2024-03-15'); if M.Matched then begin WriteLn('Year : ', GetNamedGroup(M, 'year')); WriteLn('Month : ', GetNamedGroup(M, 'month')); WriteLn('Day : ', GetNamedGroup(M, 'day')); end; { ── Find all dates in a sentence ─────────────────────────── } All := MatchAll(R, 'dates: 2024-01-01 and 2024-12-31'); for I := 0 to Length(All) - 1 do WriteLn('Found: ', All[I].FullMatch); { ── Replace with rewrite referencing named group ─────────── } var Fixed := ReplaceAll(R, 'born 1990-06-21, hired 2015-03-01', '\{day}/\{month}/\{year}'); WriteLn(Fixed); { "born 21/06/1990, hired 01/03/2015" } { ── Case-insensitive compile via options ──────────────────── } Opts.CaseInsensitive := True; var R2 := CompileEx('hello', Opts); WriteLn(IsMatch(R2, 'Say HELLO world')); { True } FreeRegex(R2); { ── Split on whitespace ──────────────────────────────────── } var Parts := Split(Compile('\s+'), 'one two three', 0); WriteLn(Parts[0], ' | ', Parts[1], ' | ', Parts[2]); FreeRegex(R); end.
← Back to Package Index