Find
Often we wish to locate the index of a substring inside another string
. In Rust, we can call find()
on a String
. A find()
function is also available on iters.
For strings, the find function searches from the start. And rfind begins at the rightmost position. A function like is_ascii_digit
can be used to match character groups.
String
findTo start, we use the find()
function in its simplest way. Find()
works in the same way as other languages like Python. But we must unwrap
the result.
find()
and get an option—this helps us determine if a value exists or not. To get the actual value, we use if let Some.find()
successfully we can use get()
to take a substring at the index returned.find()
function can work exactly like IndexOf
in other languages. It returns None
if no match is found, not -1.fn main() { // Part 1: use find as indexof. let value = "_xy_xy"; if let Some(result) = value.find("xy") { println!("INDEXOF: {result}"); } // Part 2: get substring based on index. let animals = "cat and dog"; if let Some(result) = animals.find("do") { if let Some(inner) = animals.get(result..) { println!("SUBSTRING AT DO: {inner}"); } } }INDEXOF: 1 SUBSTRING AT DO: dog
Find()
returns an option. What is the best way to handle this? The version 2 in this example is probably the best solution—we can even call find()
directly in the if
-statement.
None
, but we still need to unwrap()
the result in this case.find()
in an if
-statement, and use Some()
to unwrap
its result if it is found.fn main() { let value = "aa"; // Version 1: if no result is found, find returns None. let result = value.find("zz"); if result == None { println!("Returned None"); } // Version 2: use Some to test, and then get the actual result. let result2 = value.find("a"); if let Some(m) = &result2 { println!("{}", m); } }Returned None 0
This function does the same thing as find but proceeds from the rightmost position towards the left. It acts in reverse.
string
like the one in the example that contains two "xy" substrings.string
, rfind will find the second instance, while find will return the first.fn main() { let value = "_xy_xy"; // Use rfind to search from the right. let result = value.rfind("xy").unwrap(); println!("RFIND: {}", result); }RFIND: 4
We can pass a function or closure to the find()
function. Suppose we want to find the first digit in a string
, and take the remaining part as a substring.
is_ascii_digit
to find. Then we call get()
to extract a substring based on the first digit's position.fn main() { let value = "abc123"; // Find index of first digit. let result = value.find(|c: char| c.is_ascii_digit()).unwrap(); // Take substring of remaining chars. let numbers = value.get(result..).unwrap(); // Print results. println!("FIRST DIGIT: {}", result); println!("FIRST DIGIT START: {}", numbers); }FIRST DIGIT: 3 FIRST DIGIT START: 123
It is possible to call a find function on an iterator as well. With a vector or array, call iter()
and then call find.
find()
to get the first element that is greater than or equal to 20—this returns the value 25.find()
we may need to use the reference operator on the argument twice, which can be confusing at first.fn main() { let v = vec![10, 25, 30]; // Use find on an iter() to search a vector for a matching element. if let Some(result) = v.iter().find(|&&x| x >= 20) { println!("Greater than or equal to 20: {result}"); } }Greater than or equal to 20: 25
We search strings with the find function. We can search from start to end, and in the opposite direction. Find()
is also a function on iterators.