Drop-in for the Rust regex crate#
Full drop-in, strict by default — the regex crate’s API on REAL’s linear
engine; a pattern REAL cannot run raises Error::Unsupported instead of
silently backtracking.
Adopt / swap#
use real_regex::Regex; // drop-in for the regex crate
let re = Regex::new(r"(\w+)@(\w+)")?;
let caps = re.captures("info@example.com").unwrap();
&caps[2]; // "example"
API offered#
Regex (is_match / find / find_iter / captures / captures_iter /
replace / replace_all / split), Captures, RegexBuilder, RegexSet
(which-matched), and the bytes module — the regex crate surface, same
signatures. The opt-in fallback cargo feature adds
RegexBuilder::fallback(true): a rejected pattern delegates to the regex
crate for that pattern, trading its linear-time guarantee — engine() always
says which backend ran (Real / Fallback).
Differences & limitations#
Condensed — the full list with tables is the crate’s own README / docs.rs page:
Bounded lookarounds, a positive divergence —
(?=…)(?<=a|bb)match in linear time; theregexcrate and RE2 reject lookarounds entirely.\p{…}natively — General_Category, Script, Script_Extensions and the standard binary properties run on REAL (engine()=Real); other UAX44 namespaces raiseError::Unsupported(or delegate underfallback).CPython word/space/case semantics —
\w\sandIGNORECASEfolding follow Pythonre, not UTS#18; class-set syntax ([a[b]],&&) declines.Possessive quantifiers, a positive divergence — but silent — REAL reads
x?+/x*+/x++as possessive (the Python 3.11+ grammar); theregexcrate reads them as nested repetition. Both compile — check the README entry before migrating.shortest_matchis leftmost-first (greedy end), not earliest completion.Empty-match iteration follows the
regexcrate’s rule at the wrapper, sofind_iter/splitagree with it.
Comparison#
REAL’s closest peer on the linear-time axis. The honest duel, both ISAs, lives in the performance ledger; the reading is Performance.