2014-10-30 207 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