Is there a find
function in Rust's standard library which searches for a substring starting at a given index in the string? Just like indexOf
in JavaScript.
How to find in a substring starting at a specific index in Rust?
This is similar to Find a string starting from given index, but I find the answers there unsatisfactory because they get bogged down by OP's specific case. –
Devotee
You would use str::find
on a substr and then add the offset back:
let s = "foobarfoo";
let index: Option<usize> = s[4..].find("foo").map(|i| i + 4);
println!("{:?}", index);
Some(6)
While this is fine for ascii text, there are a few issues with this if
s
contains general unicode - since s[x..]
is the slice starting at byte x, not the x^th character. –
Tawnytawnya @MichaelAnderson True, but to avoid that it depends on what
4
means: first four bytes? first four unicode-scalar-values? first four graphemes? Those all have different answers. If we found 4
by first finding the first b
, then we already know its unicode-byte-aligned. Its also worth pointing out that String.prototype.indexOf
and std::string::find
give different results when unicode is involved. –
Devotee Those things may all give different answers, and that is fine. However
s[4..]
can panic - which is not usually the answer you want. I think if you just treat both as bytes then you at least avoid the panic. –
Tawnytawnya @MichaelAnderson, I think, 4 here is sum of the position of first occurence and length of searched string so it should always be correct position unicode char. kmdreko, it would be good if you replace magic 4 with such computation here to make it clear for new rust users. –
Swingletree
I can think of two ways:
Use the .get()
method to safely get a slice of an ASCII string and then apply .find
to that.
let s = "foobarfoo";
let res = s.get(4..).and_then(|s| s.find("foo").map(|i| i + 4));
Use match_indices
to iterate over matches and their indices and then find_map
the one that matches the first condition.
let s = "foobarfoo";
let res = s.match_indices("foo").find_map(|(i, _)| (i >= 4).then(|| i));
- Both methods will return
Some(6)
. - If the index is greater or equal to the length of the string you will
get
None
.
© 2022 - 2024 — McMap. All rights reserved.