|
REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
|
real::compat is a drop-in replacement for the <regex> surface on the char path. It runs your pattern on REAL — linear-time and ReDoS-safe — wherever that is provably identical to std::regex: the ECMAScript default and all five POSIX grammars (basic/extended/awk/grep/egrep) when the pattern translates, falling back to std::regex everywhere else. The contract in one sentence: behave identically to std::regex, never a silent divergence.** And the payoff: under the default strict policy every accepted pattern runs each regex_search / regex_match in time linear in the input — no accepted pattern can make matching super-linear, across all five POSIX grammars, where a std::regex drop-in blows up exponentially on (a+)+b. (regex_replace and the iterators compose O(n) such operations — quadratic worst-case, inherent to any linear engine, but never exponential; a nullable pattern's replace/iteration delegates to std. See real::compat — std::regex compatibility.)
Swap the include, alias the namespace, and your std::regex code compiles unchanged:
The types (regex, smatch / cmatch, sub_match, match_results, regex_error), the free functions (regex_search, regex_match, regex_replace), and the iterators (regex_iterator, regex_token_iterator) all keep their std::regex signatures and semantics — so at the call sites only the std:: qualifier changes to re::.
std::regex hang (or outright refuse) cannot happen. On the shared C++ benchmark REAL measures 11–40× faster than std::regex across the pattern families, and it stays flat on the pathological inputs where std::regex gives up. Reproduce it with make bench-engines; the machine and engine versions are in BENCHMARKS.md.[...] — routes to std::regex transparently, at construction. You never pick a backend by hand.For performance debugging, the pattern reports which engine won and why:
A pattern that unexpectedly falls to std — and so loses the linear-time guarantee — is exactly what uses_real() surfaces.
Some surfaces are always the std::regex backend by construction — they sit outside REAL's proven envelope, so compat runs std to stay a faithful drop-in: wregex and any non-char CharT or custom traits; collate and nosubs. The five POSIX grammars — basic, extended, awk, grep, egrep — are not always-std: a translatable pattern runs on REAL's linear engine with leftmost-longest bounds (see real::compat::detail::translate_posix); only an untranslatable construct (a backreference, an ECMAScript-ism, a std-library-divergent corner) delegates. There is deliberately no switch to force REAL on the always-std set — forcing it could diverge, which the contract forbids. If you need REAL's linear guarantee for such a pattern, rewrite it into the ECMAScript subset REAL accepts, then let uses_real() confirm it.
This page is the tour. The exhaustive, per-feature compatibility matrix — every routing rule, the match_flag_type support, the intentional divergences and their rationale — lives in the compatibility reference, and REAL's own (non-compat) differences from Python re are in Differences from Python re.