How do I split a string in Rust?
There is a special method split
for struct String
:
fn split<'a, P>(&'a self, pat: P) -> Split<'a, P> where P: Pattern<'a>
Split by char:
let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
Split by string:
let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
assert_eq!(v, ["lion", "tiger", "leopard"]);
Split by closure:
let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
assert_eq!(v, ["abc", "def", "ghi"]);
There are three simple ways:
By separator:
s.split("separator") | s.split('/') | s.split(char::is_numeric)
By whitespace:
s.split_whitespace()
By newlines:
s.lines()
By regex: (using
regex
crate)Regex::new(r"\s").unwrap().split("one two three")
The result of each kind is an iterator:
let text = "foo\r\nbar\n\nbaz\n";
let mut lines = text.lines();
assert_eq!(Some("foo"), lines.next());
assert_eq!(Some("bar"), lines.next());
assert_eq!(Some(""), lines.next());
assert_eq!(Some("baz"), lines.next());
assert_eq!(None, lines.next());
Use split()
let mut split = "some string 123 ffd".split("123");
This gives an iterator, which you can loop over, or collect()
into a vector.
for s in split {
println!("{}", s)
}
let vec = split.collect::<Vec<&str>>();
// OR
let vec: Vec<&str> = split.collect();
split
returns an Iterator
, which you can convert into a Vec
using collect
: split_line.collect::<Vec<_>>()
. Going through an iterator instead of returning a Vec
directly has several advantages:
split
is lazy. This means that it won't really split the line until you need it. That way it won't waste time splitting the whole string if you only need the first few values:split_line.take(2).collect::<Vec<_>>()
, or even if you need only the first value that can be converted to an integer:split_line.filter_map(|x| x.parse::<i32>().ok()).next()
. This last example won't waste time attempting to process the "23.0" but will stop processing immediately once it finds the "1".split
makes no assumption on the way you want to store the result. You can use aVec
, but you can also use anything that implementsFromIterator<&str>
, for example aLinkedList
or aVecDeque
, or any custom type that implementsFromIterator<&str>
.