What it is
The regex crate provides regular expressions with guaranteed linear-time matching, avoiding the catastrophic backtracking possible in most other engines.
Compile a Regex once and reuse it. Captures extract groups; the replace family handles substitution. Compilation is expensive, matching is fast.
Installation
cargo add regexGetting started
The smallest useful thing you can do with it, and what each part means.
rust
use regex::Regex;
use std::sync::LazyLock;
// Compiled on first use, then reused for the process lifetime.
static ISBN: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^(?<prefix>97[89])-(?<rest>[\d-]{10,})$").unwrap()
});
if let Some(caps) = ISBN.captures(input) {
println!("{} / {}", &caps["prefix"], &caps["rest"]);
}
let cleaned = ISBN.replace_all(text, "[redacted]");Advanced usage
Where the library earns its place over a simpler alternative.
rust
// Test many patterns in a single pass over the input.
let set = RegexSet::new(&[
r"^GET /api/",
r"^POST /api/",
r"\.json$",
])?;
let matched: Vec<_> = set.matches(line).into_iter().collect();
// Work on bytes when the input may not be valid UTF-8.
use regex::bytes::Regex as ByteRegex;
let re = ByteRegex::new(r"(?-u)[\x00-\x08]")?; // (?-u) disables Unicode modeErrors and fixes
The failures you are most likely to hit, and what actually resolves them.
- unrecognized escape sequence / look-around is not supported
- The pattern uses a feature this engine deliberately excludes. Rewrite it, or use the fancy-regex crate, which trades away the linear-time guarantee.
- Matching is unexpectedly slow
- Almost always recompilation in a hot path. Hoist the Regex into a static.
Best practices
- Compile once with LazyLock or OnceLock, never inside a loop or a request handler.
- Use named capture groups; positional indices break silently when the pattern changes.
- Use RegexSet when testing an input against many patterns.
- Do not look for backreferences or lookaround — they are absent by design; restructure the problem or parse it properly.
Background
Why it exists, and what it was reacting to.
Written by Andrew Gallant, the crate deliberately omits backreferences and lookaround, because supporting them would forfeit the linear-time guarantee that makes it safe on untrusted input.
