Regular Expressions in Rust: A Powerful Tool for Working with Strings
Regular expressions (regex) are an indispensable tool for searching, extracting, and replacing text based on a given pattern. In Rust, working with regular expressions is implemented through the popular regex crate, which provides high performance and safety characteristic of the language. In this article, we will cover the basics of working with regular expressions in Rust using concrete examples.
Installing and Including the regex Crate
To get started, add the dependency to your project's Cargo.toml file:
[dependencies]regex = "1"Then import the necessary modules in your code:
use regex::Regex;Creating and Basic Usage of Regular Expressions
The main type for working with regular expressions is Regex. It is created using the Regex::new() method, which takes a pattern string and returns a Result. Let's look at a simple example of searching for a word in a string:
use regex::Regex;
fn main() { let re = Regex::new(r"hello").unwrap(); let text = "hello world, hello Rust!"; // Checking for a match if re.is_match(text) { println!("Match found!"); } // Finding the first match match re.find(text) { Some(mat) => println!("Found: '{}'", mat.as_str()), None => println!("No matches"), } // Finding all matches for mat in re.find_iter(text) { println!("Found: '{}' at position {}", mat.as_str(), mat.start()); }}Note the use of a raw string (r"..."). This avoids escaping backslashes, which is especially convenient when working with regular expressions.
Capture Groups and Data Extraction
Capture groups allow you to extract parts of a string that match specific parts of the pattern. In Rust, groups are denoted by parentheses ():
use regex::Regex;
fn main() { // Extracting a date in YYYY-MM-DD format let re = Regex::new(r"(\\d{4})-(\\d{2})-(\\d{2})").unwrap(); let text = "Today: 2024-01-15, yesterday: 2024-01-14"; for cap in re.captures_iter(text) { println!("Year: {}, Month: {}, Day: {}", &cap[1], &cap[2], &cap[3]); } // Extracting email addresses let email_re = Regex::new(r"([\\w.]+)@([\\w.]+)").unwrap(); let email_text = "Contacts: user@example.com, admin@test.org"; if let Some(caps) = email_re.captures(email_text) { println!("Username: {}", &caps[1]); println!("Domain: {}", &caps[2]); }}Groups can be named to improve code readability:
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 = "2024-01-15"; if let Some(caps) = re.captures(text) { println!("Year: {}", caps.name("year").unwrap().as_str()); println!("Month: {}", caps.name("month").unwrap().as_str()); println!("Day: {}", caps.name("day").unwrap().as_str()); }}Text Replacement Using Regular Expressions
The regex crate provides powerful methods for text replacement. Let's look at several options:
use regex::Regex;
fn main() { let re = Regex::new(r"\\d+").unwrap(); let text = "I have 2 cats and 3 dogs"; // Simple replacement of all digits with a word let result = re.replace_all(text, "several"); println!("{}", result); // "I have several cats and several dogs" // Replacement using capture groups let re2 = Regex::new(r"(\\w+)@(\\w+)").unwrap(); let email = "user@example.com"; let replaced = re2.rep