The regex crate gives Rust full support for regular expressions. It lets you search, validate, extract, and replace text using familiar patterns just like in JavaScript, Python, or other languages.
I found myself reaching for regex when parsing logs in a CLI tool. Rust’s approach is different: regexes are compiled ahead of time, which makes them fast and safe. It also means your pattern is validated at compile time, so you catch typos early instead of at runtime.
This post shows you how to use regex to match patterns, capture groups, test validity, and perform text replacement all in a way that is fast, safe, and reliable.
Add regex to Your Project
In your Cargo.toml:
[dependencies]
regex = "1"
This gives you access to everything from basic matching to complex pattern parsing.
A Simple Match
To check if a pattern exists in a string:
use regex::Regex;
fn main() {
let re = Regex::new(r"\d+").unwrap();
let text = "User ID: 12345";
if re.is_match(text) {
println!("Found a number!");
}
}
- \d+ matches one or more digits
- Use r”” for raw strings so you do not need to escape every backslash
Finding Matches
To extract matching values:
let re = Regex::new(r"\d+").unwrap();
let text = "ID: 42, Code: 501";
for number in re.find_iter(text) {
println!("Found: {}", number.as_str());
}
Use this to pull values from logs, CSVs, or unstructured text.
Capturing Groups
You can name groups and extract them:
let re = Regex::new(r"Name: (?P<name>\w+), Age: (?P<age>\d+)").unwrap();
let text = "Name: Alice, Age: 30";
if let Some(caps) = re.captures(text) {
let name = &caps["name"];
let age = &caps["age"];
println!("Name: {}, Age: {}", name, age);
}
Group syntax:
- (…) = numbered group
- (?P<name>…) = named group
Validating Input
Regex is useful for checking if user input is valid:
let email_re = Regex::new(r"^[\w\.-]+@[\w\.-]+\.\w+$").unwrap();
let email = "[email protected]";
if email_re.is_match(email) {
println!("Valid email!");
} else {
println!("Invalid email.");
}
This is much safer than manually checking characters.
Replacing Text
To replace matches:
let re = Regex::new(r"\d+").unwrap();
let result = re.replace_all("Cost: 50, Tax: 5", "X");
println!("{}", result); // Output: Cost: X, Tax: X
You can also use captured values in replacements:
let re = Regex::new(r"(\d+)").unwrap();
let result = re.replace_all("Year: 2025", |caps: ®ex::Captures| {
let num: i32 = caps[1].parse().unwrap();
(num + 1).to_string()
});
println!("{}", result); // Year: 2026
This is great for modifying numbers or formatting content.
Performance Tip
Compile your regex once and reuse it:
lazy_static::lazy_static! {
static ref RE: Regex = Regex::new(r"\d+").unwrap();
}
You will need to add lazy_static to your dependencies. This avoids compiling the pattern every time.
Common Patterns
- Email: r”^[\w\.-]+@[\w\.-]+\.\w+$”
- Phone: r”\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}”
- Date: r”\d{4}-\d{2}-\d{2}”
You can copy-paste many patterns from other languages, as they mostly work the same.
Summary
The regex crate gives Rust rich and safe support for pattern matching and text parsing. You can use it to validate input, search logs, extract fields, or clean up messy data. It compiles your patterns and checks them early, so your tools are both safe and fast.
Rust Intermediate Concepts
- Generic Types in Functions and Structs
- Implementing Traits for Custom Behavior in Rust
- Trait Bounds and Constraints in Rust
- Lifetimes in Rust
- Using Closures (Anonymous Functions) in Rust
- The Iterator Trait and .next() in Rust
- Higher Order Iterator Methods: map, filter, and fold in Rust
- Using impl Trait for Simplicity in Rust
- Advanced Collections: HashSet and BTreeMap in Rust
- Custom Error Types and the Error Trait in Rust
- Option and Result Combinators in Rust
- Writing Unit Tests in Rust
- Integration Testing in Rust
- Logging in Rust with the log Crate
- Cargo Tips and Tricks for Rust Projects
- CLI Argument Parsing with Clap in Rust
- File I/O and File System Operations in Rust
- Running External Commands in Rust
- Make HTTP Requests in Rust with Reqwest
- JSON Serialization and Deserialization in Rust with Serde
- Building a Weather CLI in Rust
- Date and Time Handling in Rust with Chrono
- Using Regular Expressions in Rust with the regex Crate
- Memory Management in Rust
- Understanding Borrow Checker Errors in Rust
- Interacting with Databases in Rust
- Building a Todo List CLI in Rust with SQLite
- Concurrency in Rust