|
REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
|
real::compat::re2 — an RE2-compatible drop-in, the RE2 class surface.
More...
#include <real/version.hpp>#include <cstdint>#include <optional>#include <string>#include <string_view>#include <utility>#include <vector>#include <real/real.hpp>#include <real/regex_set.hpp>#include "arg.hpp"Classes | |
| class | real::compat::re2::RE2 |
RE2-compatible drop-in for RE2. Backed by real::regex — linear-time, ReDoS-safe. More... | |
| class | real::compat::re2::RE2::Options |
RE2-compatible construction options. Mirrors real RE2's RE2::Options field-for-field (names, defaults); see the file-level doc comment for which fields this layer honors. More... | |
| class | real::compat::re2::RE2::Set |
RE2::Set — a set of patterns tested together. Mirrors real RE2's Set: buffer patterns with Add, Compile once, then Match repeatedly. Maps directly onto REAL's native real::regex_set::which() (index-list semantics match exactly). More... | |
Namespaces | |
| namespace | real |
| REAL's public API: real::regex, real::static_regex, real::flags and the match/iterator types built on them. | |
| namespace | real::compat |
Drop-in replacements for <regex>: basic_regex, regex_search / regex_match / regex_replace and the iterator types – backed by REAL's linear-time engine where it can serve the pattern, and by std::regex otherwise, never by a silent divergence. | |
| namespace | real::compat::re2 |
| Drop-in replacement for RE2's API surface, on REAL's engine. | |
real::compat::re2 — an RE2-compatible drop-in, the RE2 class surface.
#include <real/compat/re2/re2.hpp> is the one public entry point (it pulls in re2/arg.hpp for RE2::Arg). Mirrors real RE2's own re2.h naming exactly — FullMatch, PartialMatch, QuoteMeta, set_longest_match, ANCHOR_START, … — spelled the way an RE2 user already types them, not translated to REAL's own naming conventions; that is the entire point of a drop-in.
REAL is a near-total syntax superset of RE2: it compiles everything RE2 compiles, plus bounded lookarounds and possessive quantifiers (which RE2 rejects outright) and a wider Unicode property set — namespaced \p{gc=…}/\p{sc=…}/\p{scx=…} and the UCD binary properties (\p{Alphabetic}, \p{Emoji}, …), which RE2's \p{…} grammar lacks. Two constructs are the deliberate exceptions where REAL is intentionally stricter than RE2 — principled divergences, not unimplemented gaps: (1) duplicate capturing-group names ((?P<n>…)(?P<n>…)) — RE2 tolerates them; REAL rejects them because its named-capture lookup (match-by-name) would be ambiguous with a repeated name (capture-safety); (2) surrogate code points in \x{…}/\u/\U/\N (e.g. \x{D800}) — RE2 does not validate them, REAL rejects them through the same Unicode-scalar validation it applies to every code-point escape. Both surface as a clean ok() == false, and are the only two entries in this layer's fuzz_re2 KNOWN-GAP ledger. So this wraps real::regex / real::regex_set directly: no RE2 dependency at runtime (header-only, zero-dep; RE2 is a test-time oracle only, never linked by this header or anything it includes).
No fallback policy. The std::regex compat layer can delegate an ineligible pattern to std::regex (policy::fallback) because std::regex is always there. RE2 is not a runtime dependency here, so there is nothing to fall back to: a pattern or option this layer cannot honor is a clean, immediate rejection (ok() == false, error() explains why) — the same shape RE2 itself uses for a syntax error, so callers already know how to handle it. RE2 itself has no exceptions (RE2 re("(broken"); if (!re.ok()) …); this layer follows that contract rather than std::regex's throwing one.
Scope. Matches RE2's default mode (Options::posix_syntax() == false, Options::encoding() == Options::EncodingUTF8) — REAL's own text mode is the documented parity point (codepoint-aware, flags::ecma-free since RE2 is Perl-flavored, not ECMAScript-flavored). posix_syntax, Latin-1, never_nl, and never_capture have no REAL-side equivalent and are rejected at construction (ErrorUnsupported) rather than silently ignored; perl_classes, word_boundary, and one_line are inert here for the same reason they are inert in real RE2 outside posix_syntax mode (its own documented behavior, not a new divergence). longest_match is honored by every unanchored-search operation — PartialMatch, FindAndConsume, Replace, GlobalReplace — via real::regex::search_longest()/find_iter_longest(), REAL's own, pre-existing, documented RE2 set_longest_match equivalents; FullMatch/Consume's anchored boundaries do not depend on it (matching text is matching text end-to-end either way), and its effect on capture tie-breaking inside an ambiguous alternation is the same non-POSIX-submatch caveat RE2 itself documents as shared, not a new one.
**\C (RE2's raw-byte escape) is accepted**, matching real RE2's own default-mode behavior exactly: it consumes exactly one byte, unconditionally, possibly landing mid-codepoint. Safe here specifically because this layer's whole API is byte-offset C++ (mirroring RE2's own) — the char-offset hazard that keeps \C gated to flags::bytes on REAL-native, char-offset surfaces (e.g. the Python str binding, which cannot reach this flag) never applies to real::compat::re2.