8

I am doing some processing of a string in Rust, and I need to be able to extract the last set of characters from that string. In other words, given a string like the following:

some|not|necessarily|long|name

I need to be able to get the last part of that string, namely "name" and put it into another String or a &str, in a manner like:

let last = call_some_function("some|not|necessarily|long|name");

so that last becomes equal to "name".

Is there a way to do this? Is there a string function that will allow this to be done easily? If not (after looking at the documentation, I doubt that there is), how would one do this in Rust?

Factor Three
  • 2,094
  • 5
  • 35
  • 51
  • Does this answer your question? [How do I split a string in Rust?](https://stackoverflow.com/questions/26643688/how-do-i-split-a-string-in-rust) – Chris Dec 13 '21 at 20:24
  • Actually, no it doesn't. The code at the link you provided appears to actually *remove* the part I am looking for. This would cause "some|not|necessarily|long|name" to return "some|not|necessarily|long|". That is what I am seeing when I test that code. – Factor Three Dec 13 '21 at 21:07
  • But what happens if you split on `"|"` and take the last element returned? – Chris Dec 13 '21 at 21:10

2 Answers2

16

While the answer from @effect is correct, it is not the most idiomatic nor the most performant way to do it. It'll walk the entire string and match all of the |s to reach the last. You can make it better, but there is a method of str that does exactly what you want - rsplit_once():

let (_, name) = s.rsplit_once('|').unwrap();
// Or
// let name = s.rsplit_once('|').unwrap().1;
//
// You can also use a multichar separator:
// let (_, name) = s.rsplit_once("|").unwrap();
// But in the case of a single character, a `char` type is likely to be more performant.

Playground.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
11

You can use the String::split() method, which will return an iterator over the substrings split by that separator, and then use the Iterator::last() method to return the last element in the iterator, like so:

let s = String::from("some|not|necessarily|long|name");
let last = s.split('|').last().unwrap();
    
assert_eq!(last, "name");

Please also note that string slices (&str) also implement the split method, so you don't need to use std::String.

let s = "some|not|necessarily|long|name";
let last = s.split('|').last().unwrap();
    
assert_eq!(last, "name");
Chris
  • 26,361
  • 5
  • 21
  • 42
effect
  • 1,279
  • 6
  • 13
  • This is a great solution and it works, but the solution below appears to be more efficient and, based on my testing, faster. I did give yours an up- vote because it was the first working solution to my problem. – Factor Three Dec 20 '21 at 14:07