Substring
In Rust we often need to extract a certain range of characters from a string
. We want the first 2 characters, or the last several characters.
No substring()
function is available directly in Rust, but we can take slices or use the get()
function. These functions take substrings.
To begin, we have a Rust program that introduces a short string literal. We want to take the middle 2 chars of the string
"bird."
get()
function and unwrap
its result. The result is the same.fn main() { let value = "bird"; // Version 1: use slice syntax to take substring. let result1 = &value[1..3]; println!("SUBSTRING: {}", result1); // Version 2: use get() to take substring. let result2 = value.get(1..3).unwrap(); println!("SUBSTRING: {}", result2); }SUBSTRING: ir SUBSTRING: ir
We can omit the first or last index from the slice syntax. If we omit an index, it is assumed to be either the first or last possible index.
len()
to count back 2 from the total string
length.fn main() { let value = "abcdef"; // Get first 2 characters. let result1 = &value[..2]; println!("SUBSTRING: {}", result1); // Get last 2 characters. let result1 = &value[value.len()-2..]; println!("SUBSTRING: {}", result1); }SUBSTRING: ab SUBSTRING: ef
In Rust programs, using the String
type is often simplest as it indicates ownership. A String
owns its own data. To store substrings, we can convert them to Strings.
if-let
syntax to get 2 substrings from the source string
. We then convert them to Strings with to_string
.Result
struct
has 2 Strings, and it will own the string
data in those objects.str
references can speed up programs, but in the real world, using Strings and copying is easier.#[derive(Debug)] struct Result { a: String, b: String } fn main() { let source = "1234".to_string(); let mut part1 = String::new(); let mut part2 = String::new(); // Get left substring. if let Some(part) = source.get(0..2) { part1 = part.to_string(); } // Get right substring. if let Some(part) = source.get(2..) { part2 = part.to_string(); } // Place substrings in struct. let result = Result{a: part1, b: part2}; println!("{:?}", result); }Result { a: "12", b: "34" }
Sometimes we may have an array or vector of u8
values (bytes). We can get a String
from these values by using from_utf8_lossy
.
String
, so may be a better choice in some programs.fn main() { let data = vec![b'a', b'b', b'c', b'd']; // If we need a String, not a str, we can use from utf8 lossy. let result = String::from_utf8_lossy(&data[0..=2]); println!("{result}"); }abc
Taking substrings in Rust amounts to taking slices and being familiar with slice syntax. The get()
function does the same thing as slice, but avoids errors.