I looked at the Rust docs for String
but I can't find a way to extract a substring.
Is there a method like JavaScript's substr
in Rust? If not, how would you implement it?
str.substr(start[, length])
The closest is probably slice_unchecked
but it uses byte offsets instead of character indexes and is marked unsafe
.
Crate substring[−][src] This crate provides a substring() method on Rust string types. The method takes a start and end character index and returns a string slice of the characters within that range. The method is provided via the Substring trait which is implemented on the str primitive.
Indexing into a string is often a bad idea because it's not clear what the return type of the string-indexing operation should be: a byte value, a character, a grapheme cluster, or a string slice. It's one of the reasons why the Rust compiler does not allows the direct access to characters in strings.
The difference between substring() and substr()The two parameters of substr() are start and length , while for substring() , they are start and end . substr() 's start index will wrap to the end of the string if it is negative, while substring() will clamp it to 0 .
slice() extracts parts of a string and returns the extracted parts in a new string. substr() extracts parts of a string, beginning at the character at the specified position, and returns the specified number of characters. substring() extracts parts of a string and returns the extracted parts in a new string.
For characters, you can use s.chars().skip(pos).take(len)
:
fn main() { let s = "Hello, world!"; let ss: String = s.chars().skip(7).take(5).collect(); println!("{}", ss); }
Beware of the definition of Unicode characters though.
For bytes, you can use the slice syntax:
fn main() { let s = b"Hello, world!"; let ss = &s[7..12]; println!("{:?}", ss); }
You can use the as_str
method on the Chars
iterator to get back a &str
slice after you have stepped on the iterator. So to skip the first start
chars, you can call
let s = "Some text to slice into"; let mut iter = s.chars(); iter.by_ref().nth(start); // eat up start values let slice = iter.as_str(); // get back a slice of the rest of the iterator
Now if you also want to limit the length, you first need to figure out the byte-position of the length
character:
let end_pos = slice.char_indices().nth(length).map(|(n, _)| n).unwrap_or(0); let substr = &slice[..end_pos];
This might feel a little roundabout, but Rust is not hiding anything from you that might take up CPU cycles. That said, I wonder why there's no crate yet that offers a substr
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With