Strings and Text Processing
find() and matches()
str provides pattern-searching methods that locate the byte offset of a match (.find(), .rfind()) or iterate over all non-overlapping matches (.matches(), .match_indices()).
Reference of Search and Match Methods on str
| Method | Search Direction | Return Type | What It Yields |
|---|---|---|---|
s.find(pat) |
Left to right | Option<usize> |
Starting UTF-8 byte index of the first match |
s.rfind(pat) |
Right to left | Option<usize> |
Starting UTF-8 byte index of the last match |
s.matches(pat) |
Left to right | Matches<'_, P> |
Iterator of matched &str substrings |
s.rmatches(pat) |
Right to left | RMatches<'_, P> |
Iterator of matched &str substrings from the right |
s.match_indices(pat) |
Left to right | MatchIndices<'_, P> |
Iterator of (usize, &str) ((byte_offset, matched_slice)) |
s.rmatch_indices(pat) |
Right to left | RMatchIndices<'_, P> |
Iterator of (usize, &str) from the right |
Locating Byte Offsets with .find() and .rfind()
Every index returned by .find() or .rfind() is guaranteed to be a valid UTF-8 character boundary suitable for string slicing:
fn main() {
let path = "/home/prime/projects/rust/Cargo.toml";
if let Some(first_slash) = path.find('/') {
println!("First '/' at byte {first_slash}");
}
if let Some(last_slash) = path.rfind('/') {
let dir = &path[..last_slash];
let file = &path[last_slash + 1..];
println!("Dir: '{dir}'");
println!("File: '{file}'");
}
}
First '/' at byte 0
Dir: '/home/prime/projects/rust'
File: 'Cargo.toml'
Extracting All Matches and Their Offsets with .matches() and .match_indices()
fn main() {
let log = "err[E0308] at line 4, err[E0502] at line 19";
// 1. Collect all substrings matching the digit predicate:
let digits: Vec<&str> = log.matches(|c: char| c.is_ascii_digit()).collect();
println!("Individual digits: {digits:?}");
// 2. Find every occurrence of "err" along with its starting byte offset:
for (byte_pos, matched) in log.match_indices("err") {
let code = &log[byte_pos..byte_pos + 10];
println!("Matched '{matched}' at byte {byte_pos:>2} -> {code}");
}
}
Individual digits: ["0", "3", "0", "8", "4", "0", "5", "0", "2", "1", "9"]
Matched 'err' at byte 0 -> err[E0308]
Matched 'err' at byte 22 -> err[E0502]