Rust Regex Captures
Capture groups are parts of a regex pattern, marked with parentheses, that save the pieces of a match.
Parentheses save a piece
The digits land in group 1. The word apples is matched but not saved.
let re = Regex::new(r"(\d+) apples").unwrap();
let caps = re.captures("she has 12 apples").unwrap();
println!("count = {}", &caps[1]);Group 0 is the whole match
Numbering starts at 0 for the whole match. Real groups count from 1.
let re = Regex::new(r"(\d+)-(\d+)").unwrap();
let caps = re.captures("on 2026-10").unwrap();
println!("whole = {}, first = {}, second = {}", &caps[0], &caps[1], &caps[2]);Names beat numbers
A named group reads better than a bare number. The date groups carry their jobs as names.
let re = Regex::new(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})").unwrap();
let caps = re.captures("on 2026-10-22 today").unwrap();
println!("{}-{}-{}", &caps["year"], &caps["month"], &caps["day"]);A group can miss
The (x)? group is allowed to stay home. On this text it did.
let re = Regex::new(r"(\d+)(x)?").unwrap();
let caps = re.captures("42").unwrap();
println!("suffix = {:?}", caps.get(2));captures_iter walks every match
Settings files love key=value pairs. One pattern picks both halves out of each pair.
let re = Regex::new(r"(\w+)=(\w+)").unwrap();
for caps in re.captures_iter("host=web port=8080") {
println!("{} -> {}", &caps[1], &caps[2]);
}Example
// Cargo.toml: regex = "1"
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 = "start 2026-10-22 end 2026-11-01";
for caps in re.captures_iter(text) {
println!("day {} of month {} in year {}", &caps["day"], &caps["month"], &caps["year"]);
}
}Key points
- A pair of ( ) in a pattern is a capture group: it saves the part of the text it matched
- A capture group saves one piece of the match, so the pieces can be used one by one.
- Use captures to get the first match with its groups, and captures_iter to walk every match in the text
- Group 0 is always the whole match, and groups 1, 2, and 3 count the ( ) pairs from the left
- A group can carry a name: (?P<year>...) names it.
- Read a named group back with caps["year"].
- A group that took no part gives None.
- Read groups with get() when a miss is possible.
In this example, one text holds two dates. The pattern names its three groups: year, month, and day. captures_iter finds the first date and hands back its groups. It then finds the second date and does the same. Each line prints the pieces in day, month, year order. The names make the print line read like the fact it states.
Note
Groups nest: a group inside a group still gets its own number, counted by its opening ( from the left.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
In a match, what is group 0?