RE2 compatibility layer#
RE2 compatibility layer, strict — real::compat::re2, header-only, zero-dep.
The parts of the RE2 surface listed below, on REAL’s linear engine; every accepted pattern is
guaranteed linear, and a construct this layer cannot honor is a clean
ok() == false — RE2’s own no-exception contract, never a silent backtrack.
RE2 itself is a test-time oracle only, never linked.
Adopt / swap#
#include <real/compat/re2/re2.hpp>
using real::compat::re2::RE2;
std::string user, host;
RE2::PartialMatch("info@example.com", R"((\w+)@(\w+))", &user, &host);
// host == "example" — group 2, via RE2's typed Arg extraction
API offered#
Statics —
FullMatch/PartialMatch/Consume/FindAndConsume(typedRE2::Argextraction: one&int,&std::string, … per group),Replace/GlobalReplace,QuoteMeta.Instance —
ok()/error()/error_code()/pattern()/NumberOfCapturingGroups().RE2::Options—set_longest_matchis honored by every unanchored search, andset_max_membounds the compiled program as RE2’s does (a pattern past two thirds of it fails withErrorPatternTooLarge, counted in bytes of REAL’s program);log_errors()readstrueby default, as RE2’s, and an explicitset_log_errors(true)makes a failed compile write RE2’s stderr message (Error parsing '<pattern>': <error>), withok()/error()unchanged – nothing is written unless it was asked for; options with no REAL-side equivalent are rejected at construction, never silently ignored (details below).RE2::Set— Add / Compile / Match, multi-pattern which-matched onreal::regex_set.Spelled as RE2 spells them — the canned option sets (
RE2 re(p, RE2::Quiet);Latin1andPOSIXare rejected at construction),RE2::UNANCHORED/ANCHOR_START/ANCHOR_BOTH,RE2::NoError/ErrorPatternTooLarge, andLazyRE2(static LazyRE2 re = {"a+"};, compiled once on first use, from any thread).Not provided — the low-level
RE2::Match,NamedCapturingGroups/CapturingGroupNames,Extract/Rewrite/CheckRewriteString/MaxSubmatch, the*Nstatics,CRadix/Hex/Octal,error_arg(), theProgram*diagnostics, and RE2’s fine-grained error codes (this layer reportsErrorSyntax/ErrorUnsupported/ErrorPatternTooLarge).
One include: <real/compat/re2/re2.hpp>. Object-level reference:
RE2 compatibility.
Differences & limitations#
Distilled from the layer’s own contract — the exhaustive version is the file
comment of
re2.hpp:
REAL is a near-total syntax superset — everything RE2 compiles, plus bounded lookarounds and possessive quantifiers (RE2 rejects both outright) and a wider
\p{…}set (sc=/scx=and the UCD binary properties RE2’s grammar lacks).RE2’s reading of the syntax —
\w,\d,\sare ASCII,\b/\Bread ASCII word characters,[[:alpha:]]is a POSIX class,$without(?m)is the end of the text, andGlobalReplacesteps past an empty match as RE2 does. Checked against libre2 over every code point. One orbit differs: under(?i),İ/ı(U+0130, U+0131) fold withi/I, as in Python’sre, where RE2 keeps them apart.Two places REAL is deliberately stricter — duplicate capture names (
(?P<n>…)(?P<n>…), ambiguous match-by-name) and surrogate code points in\x{…}/\u/\U/\N. Both a cleanok() == false; both principled divergences, and the only two entries in this layer’s differential-fuzz known-gap ledger.No fallback — RE2 is not a runtime dependency, so there is nothing to delegate to: an unsupported pattern or option rejects immediately with
error()explaining why (unlike thestd::regexlayer’s opt-in fallback).Scope is RE2’s default mode — UTF-8, non-POSIX.
posix_syntax, Latin-1,never_nl,never_capturereject at construction;perl_classes/word_boundary/one_lineare inert exactly as in real RE2 outside POSIX mode.\Cis accepted — one byte, possibly mid-codepoint, safe on this byte-offset API.
Comparison#
Single-pattern numbers against RE2, PCRE2-JIT and std::regex live in the
performance ledger;
the reading is Performance. RE2 cannot compile
the lookaround row at all.
Multi-pattern is covered too: RE2::Set compiles into real::regex_set, a
shipped hybrid — per-pattern walks below a calibrated set size (competitive
there, sometimes the fastest route), and above it the DFA-eligible members
switch automatically onto a fused single-pass scan that stays flat as the set
grows. Measured against Google’s RE2::Set on the same host it is near
parity — ahead on sparse corpora, a hair behind on dense ones. The residual
cuts both ways: lookaround patterns stay on per-pattern walks
and degrade at large N — but RE2::Set cannot compile a lookaround at all,
and REAL leads on multi-pattern extraction. Numbers in
Performance.