Strings and Text Processing
split() and split_whitespace()
str provides a rich family of zero-allocation splitting iterators that yield &str substrings borrowing directly from the source string without copying bytes onto the heap.
Reference of Splitting Methods on str
| Method | Delimiter / Rule | Trailing Empty Behavior | Returns |
|---|---|---|---|
s.split(pat) |
char, &str, &[char], or FnMut(char) -> bool |
Preserves trailing "" after a final delimiter |
Iterator<Item = &str> |
s.rsplit(pat) |
Same as split, scanned from the right |
Preserves leading "" |
Iterator<Item = &str> |
s.split_terminator(pat) |
Same as split, treating trailing delimiter as a terminator |
Drops trailing "" after a final delimiter |
Iterator<Item = &str> |
s.splitn(n, pat) |
Splits into at most n pieces (last piece contains the unsplit remainder) |
Preserves empty fields | Iterator<Item = &str> |
s.split_once(pat) |
Splits at the first delimiter into a 2-tuple | Returns None if delimiter is absent |
Option<(&str, &str)> |
s.rsplit_once(pat) |
Splits at the last delimiter into a 2-tuple | Returns None if delimiter is absent |
Option<(&str, &str)> |
s.split_whitespace() |
Splits on runs of any Unicode whitespace (char::is_whitespace) |
Skips leading, trailing, and consecutive whitespace | Iterator<Item = &str> |
s.split_ascii_whitespace() |
Splits on runs of ASCII whitespace (' ', '\t', '\n', '\r', '\x0C') |
Skips leading, trailing, and consecutive whitespace | Iterator<Item = &str> |
Comparing split(), split_terminator(), and split_whitespace()
"a,b,"
├── .split(',') ──> ["a", "b", ""] (3 items; trailing "" kept)
└── .split_terminator(',') ──> ["a", "b"] (2 items; trailing "" dropped)
" hello world \t\n "
└── .split_whitespace() ──> ["hello", "world"]
fn main() {
let csv = "alpha,beta,";
println!("split(','): {:?}", csv.split(',').collect::<Vec<_>>());
println!(
"split_terminator(','): {:?}",
csv.split_terminator(',').collect::<Vec<_>>()
);
let messy = " rust\t\t2024\n edition ";
let words: Vec<&str> = messy.split_whitespace().collect();
println!("split_whitespace(): {words:?}");
}
split(','): ["alpha", "beta", ""]
split_terminator(','): ["alpha", "beta"]
split_whitespace(): ["rust", "2024", "edition"]
Parsing Key-Value Pairs with split_once() and rsplit_once()
When splitting a string into exactly two parts (such as KEY=VALUE or filename.ext), prefer .split_once() and .rsplit_once() over .splitn(2, ...) because they return Option<(&str, &str)> directly without constructing an iterator:
fn main() {
let header = "Authorization: Bearer secret:token";
if let Some((name, value)) = header.split_once(": ") {
println!("Header '{name}' = '{value}'");
}
let filename = "archive.tar.gz";
if let Some((stem, ext)) = filename.rsplit_once('.') {
println!("Stem: '{stem}', extension: '{ext}'");
}
}
Header 'Authorization' = 'Bearer secret:token'
Stem: 'archive.tar', extension: 'gz'