str::find¶
Level: reference · for working programmers
One line: The byte offset of the first match, as Option<usize> — None when there is none, never -1.
Stable since 1.0.0.
The return is an Option, which is the whole difference from the C-family indexOf returning -1: there is no sentinel to forget to check, and the type system will not let you use the offset until you have dealt with the miss.
The offset is in bytes, and it is always on a character boundary, so it is safe to slice at:
fn main() {
let s = "key=value";
if let Some(i) = s.find('=') { println!("{:?} {:?}", &s[..i], &s[i + 1..]); }
}
That i + 1 is only right because '=' is one byte. For a multi-byte or &str pattern the end of the match is i + pat.len() — which is exactly the arithmetic split_once does for you, and the reason to prefer it for this shape.
A predicate pattern finds the first character satisfying it, which is how you locate the first digit or the first non-ASCII character in one call.
Example¶
str_find.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let s = "key=value=more";
println!("{:?}", s.find('='));
println!("{:?}", s.find("value"));
println!("{:?}", s.find(char::is_numeric)); // None, not -1
// Splitting by hand — correct, but the +1 is the pattern's byte length.
if let Some(i) = s.find('=') {
println!("{:?} / {:?}", &s[..i], &s[i + 1..]);
}
// The same thing, with no arithmetic to get wrong.
println!("{:?}", s.split_once('='));
// Byte offsets, so a wide character shifts everything after it.
let wide = "héllo=x";
println!("{:?} at byte {:?}", '=', wide.find('='));
// First character matching a predicate.
println!("{:?}", "abc123".find(char::is_numeric));
}
Verified output of str_find.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
str::rfind— the last match instead of the firststr::split_once— find-and-slice, without the arithmeticstr::match_indices— every match with its offsetstr::contains— when you only need whether, not where
str::find in the standard library ↗
Po polsku¶
Od find z Pythona — czy indexOf z Javy — różnią tę metodę dwie rzeczy. Po pierwsze zwraca Option<usize>, a nie -1: nie ma wartownika, o którego sprawdzeniu dałoby się zapomnieć, bo system typów nie wypuści przesunięcia, dopóki nie obsłużysz przypadku „nie znaleziono”. Po drugie liczba w środku to przesunięcie w bajtach, więc na polskim tekście nie zgadza się z pozycją znaku — "żółw=x".find('=') da Some(7), a nie Some(4), dokładnie tak jak "héllo=x" z przykładu powyżej daje Some(6). To przesunięcie zawsze wypada na granicy znaku, więc wolno przy nim ciąć, ale &s[i + 1..] jest poprawne wyłącznie wtedy, gdy wzorzec ma jeden bajt; koniec dopasowania to i + pat.len(), a najbezpieczniej niczego nie liczyć i sięgnąć po split_once.
Szukaj po polsku: wyszukiwanie w łańcuchu znaków · przesunięcie bajtowe · rust str find Option · rust split_once