Strings and Text Processing
trim() and Related Methods
str provides zero-allocation trimming and prefix/suffix stripping methods that adjust the start pointer and length of a &str slice without modifying or copying the underlying bytes.
Reference of Trimming and Stripping Methods
| Method | What It Removes | Return Type |
|---|---|---|
s.trim() |
Leading and trailing Unicode whitespace (char::is_whitespace) |
&str |
s.trim_start() |
Leading Unicode whitespace only | &str |
s.trim_end() |
Trailing Unicode whitespace only | &str |
s.trim_ascii() |
Leading and trailing ASCII whitespace (' ', '\t', '\n', '\r', '\x0C') |
&str (const fn) |
s.trim_matches(pat) |
Leading and trailing characters matching pat (char, &[char], or predicate) |
&str |
s.trim_start_matches(pat) |
Leading characters or repeated prefix matching pat |
&str |
s.trim_end_matches(pat) |
Trailing characters or repeated suffix matching pat |
&str |
s.strip_prefix(pat) |
At most one leading occurrence of pat; returns None if absent |
Option<&str> |
s.strip_suffix(pat) |
At most one trailing occurrence of pat; returns None if absent |
Option<&str> |
Original: " hello world\n " (ptr = p, len = 17)
└───┬─────┘
s.trim(): "hello world" (ptr = p + 3, len = 11 — zero heap allocation!)
Trimming Whitespace and Custom Delimiters
fn main() {
let raw = " \t rust-2024 \r\n ";
println!("trim(): {:?}", raw.trim());
println!("trim_start(): {:?}", raw.trim_start());
println!("trim_end(): {:?}", raw.trim_end());
let wrapped = "***[IMPORTANT]***";
println!(
"trim_matches: {:?}",
wrapped.trim_matches(&['*', '[', ']'][..])
);
}
trim(): "rust-2024"
trim_start(): "rust-2024 \r\n "
trim_end(): " \t rust-2024"
trim_matches: "IMPORTANT"
Why You Usually Want strip_prefix() Instead of trim_start_matches()
A subtle bug arises when using trim_start_matches("prefix") or trim_end_matches("suffix") with a &str or character set:
trim_start_matches(pat)removes all repeated occurrences ofpatand always returns a&streven ifpatwas not present.strip_prefix(pat)andstrip_suffix(pat)check whethersstarts or ends withpat, remove exactly one occurrence, and returnSome(rest)(orNoneifpatdid not match):
fn main() {
let token_header = "Bearer Bearer_secret";
// `strip_prefix` removes "Bearer " once and returns `Option<&str>`:
if let Some(token) = token_header.strip_prefix("Bearer ") {
println!("Extracted token: '{token}'");
}
let path = "/var/log/app.log.log";
println!("strip_suffix: {:?}", path.strip_suffix(".log"));
println!("trim_end_matches: {:?}", path.trim_end_matches(".log"));
}
Extracted token: 'Bearer_secret'
strip_suffix: Some("/var/log/app.log")
trim_end_matches: "/var/log/app"