Regular Expressions in Rust with Examples: In Practice

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Do You Need Regular Expressions in Rust?

Regular expressions (regex) are a powerful tool for searching, extracting, and replacing text based on patterns. In Rust, working with regular expressions is implemented through the regex crate, which is considered one of the fastest and safest in the ecosystem. Unlike many other languages, the Rust compiler checks the validity of a regular expression at compile time (if using the regex! macro), which helps avoid errors during execution.

In this article, we will explore practical examples of using regular expressions in Rust: from basic search to complex data extraction. You will learn how to set up a project, write patterns, and process results.



1. Project Setup and First Regex

Adding the Dependency

First, add the regex crate to your Cargo.toml file:

[dependencies]regex = "1"

Then update the dependencies with the command cargo build.



First Example: Searching for a Word

Let's write a simple program that finds the word "Rust" in a string:

use regex::Regex;

fn main() { let re = Regex::new(r"Rust").unwrap(); let text = "I am learning Rust and Python."; if re.is_match(text) { println!("Word 'Rust' found!"); } else { println!("Word not found."); }}

The Regex::new function compiles the pattern. If the pattern is invalid, the program will terminate with an error (use unwrap() only in prototypes).



2. Data Extraction Using Captures

Grouping and Named Groups

Regular expressions allow you to extract parts of text using parentheses. Consider an example with an email:

use regex::Regex;

fn main() { let re = Regex::new(r"(?P<name>[a-zA-Z0-9._%+-]+)@(?P<domain>[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})").unwrap(); let text = "My email: user@example.com, and also admin@test.org."; for caps in re.captures_iter(text) { println!("Name: {}", &caps["name"]); println!("Domain: {}", &caps["domain"]); }}

In this example, we use named groups (?P<name>...). This makes the code more readable and convenient for further processing.



Extracting All Matches

If you need to get all matches without groups, use find_iter:

use regex::Regex;

fn main() { let re = Regex::new(r"\\d+").unwrap(); let text = "Prices: 100, 250, and 500 rubles."; for mat in re.find_iter(text) { println!("Found number: {}", mat.as_str()); }}

The find_iter method returns an iterator over Match objects, which contain the start and end positions, as well as the matched text itself.



3. Text Replacement and Complex Patterns

Simple Replacement

Let's replace all digits with the word "NUMBER":

use regex::Regex;

fn main() { let re = Regex::new(r"\\d+").unwrap(); let text = "Code: 12345, status: 0."; let result = re.replace_all(text, "NUMBER"); println!("{}", result); // "Code: NUMBER, status: NUMBER."}


Replacement Using Captures

You can reference groups in the replacement string using $1, $2, or named groups $name:

use regex::Regex;

fn main() { let re = Regex::new(r"(?P<year>\\d{4})-(?P<month>\\d{2})-(?P<day>\\d{2})").unwrap(); let text = "Date: 2024-03-15"; let result = re.replace_all(text, "$day.$month.$year"); println!("{}", result); // "Date: 15.03.2024"}


Complex Pattern: Log Parsing

Let's look at a real-world example — parsing a web server log line:

use regex::Regex;

fn main() { let log_line =

Blogs

Book Recommendations