Drop-in for RE2#
Full drop-in, strict — real::compat::re2, header-only, zero-dep. The RE2
surface you already type, 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; 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.
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).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 and Unicode-\w 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.