2014-10-30 174 views
49

如何在Rust中分割字符串?目前尚不清楚,从its documentation。在Java中我会做到这一点的:如何在Rust中拆分字符串?

"some string 123 ffd".split("123"); 
+0

https://doc.rust-lang.org/std/string/struct.String.html – 2016-10-29 02:10:16

+0

@bow有没有办法使它成为一个字符串数组而不是矢量? – Greg 2017-11-07 07:25:37

+0

我不知道有任何方法可以做到这一点,至少是直接的。您可能需要手动迭代“Split”并将其设置到数组中。当然,这意味着每个分割中的项目数量必须相同,因为数组的大小是固定的,您必须先定义数组。我想这可能比简单创建一个'Vec'更麻烦。 – bow 2017-11-07 07:37:08

回答

64

使用split()

let mut split = "some string 123 ffd".split("123"); 

这给出了一个迭代器,你可以遍历或collect()到载体中。

for s in split { 
    println!("{}", s) 
} 
let vec = split.collect::<Vec<&str>>(); 
// OR 
let vec: Vec<&str> = split.collect(); 
+8

你也可以写成'.collect :: >()'。 – 2014-10-30 02:19:48

+0

我如何得到结果的长度 - “让分裂”? 'split.len()'不存在。 – 2014-10-30 14:00:38

+1

@AlexanderSupertramp使用'.count()'。 'len()'仅适用于知道它们的确切大小而不需要消耗的迭代器,'count()'消耗迭代器。 – Manishearth 2014-10-30 18:16:11

12

有一种特殊的方法split for struct String

fn split<'a, P>(&'a self, pat: P) -> Split<'a, P> where P: Pattern<'a> 

分割成炭:

let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); 
assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); 

通过分割字符串:

let v: Vec<&str> = "lion::tiger::leopard".split("::").collect(); 
assert_eq!(v, ["lion", "tiger", "leopard"]); 

斯普利特关闭:

let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); 
assert_eq!(v, ["abc", "def", "ghi"]); 
4

还有split_whitespace()

fn main() { 
    let words: Vec<&str> = " foo bar\t\nbaz ".split_whitespace().collect(); 
    println!("{:?}", words); 
    // ["foo", "bar", "baz"] 
} 
11

有三种简单的方法:

  1. 通过分离

    s.split("separator") 
    
  2. 通过空白

    s.split_whitespace() 
    
  3. 通过换行符

    s.lines() 
    

每一种的结果是一个迭代器:

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()); 
5

split返回Iterator,你可以转换我nto a Vec using collectsplit_line.collect::<Vec<_>>()。直接通过迭代器而不是直接返回Vec有几个优点:

  • split是懒惰的。这意味着它不会真正分割线路直到你需要它。这样,如果您只需要前几个值,则不会浪费时间分割整个字符串:split_line.take(2).collect::<Vec<_>>(),或者即使您只需要第一个可以转换为整数的值:split_line.filter_map(|x| x.parse::<i32>().ok()).next()。最后一个示例不会浪费时间来尝试处理“23.0”,但一旦找到“1”就会立即停止处理。
  • split对您想要存储结果的方式没有任何假设。您可以使用Vec,但您也可以使用任何实施FromIterator<&str>的项目,例如LinkedListVecDeque或实施FromIterator<&str>的任何自定义类型。
+0

谢谢您的详细回答,为什么'let x = line.unwrap()。split(“,”)。collect :: >();'不起作用,除非它分成两行:''让x = line.unwrap();'和'let x = x.split(“,”)。collect :: >();'?错误消息说:'此处创建的临时值^暂时值在此处仍然被借用' – Greg 2017-11-07 10:53:07

+0

但是,如果我使用'let x = line.as_ref()。unwrap()。split(“,”)。 :: >();' – Greg 2017-11-07 10:58:33