2014-10-30 12 views
49

Làm cách nào để tách chuỗi trong Rust? Từ its documentation không rõ ràng. Trong Java Tôi muốn làm điều đó bằng:Làm thế nào để tách một chuỗi trong Rust?

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

https://doc.rust-lang.org/std/string/struct.String.html –

+0

@bow Có cách nào để biến nó thành mảng String thay vì véc tơ không? – Greg

+0

Tôi không biết cách nào để làm điều đó, trực tiếp ít nhất. Bạn có thể phải tự lặp qua 'Tách' và đặt nó vào mảng. Tất nhiên điều này có nghĩa là số lượng các mục trong mỗi phân chia phải giống nhau vì các mảng có kích thước cố định và bạn phải có mảng được xác định trước đó. Tôi tưởng tượng điều này có thể rắc rối hơn là chỉ tạo ra một 'Vec'. – bow

Trả lời

64

Sử dụng split()

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

này đưa ra một iterator, mà bạn có thể lặp kết thúc, hoặc collect() vào một vector.

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

Bạn cũng có thể viết nó '.collect :: >()'. –

+0

làm cách nào để có được độ dài của kết quả - 'để chia nhỏ'? 'split.len()' không tồn tại. –

+1

@AlexanderSupertramp Sử dụng '.count()'. 'len()' chỉ dành cho các trình vòng lặp mà biết kích thước chính xác của chúng mà không cần phải tiêu thụ, 'count()' tiêu thụ trình lặp. Lỗi – Manishearth

12

Có một phương pháp đặc biệt split for struct String:

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

Chia bởi char:

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

Chia bởi chuỗi:

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

Chia bởi việc đóng cửa:

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

Ngoài ra còn có split_whitespace()

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

Có ba cách đơn giản:

  1. By tách:

    s.split("separator") 
    
  2. By khoảng trắng:

    s.split_whitespace() 
    
  3. By newlines:

    s.lines() 
    

Kết quả của từng loại là một 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()); 
5

split trả về một Iterator, mà bạn có thể chuyển đổi i vào một số điện thoại Vec sử dụng collect: split_line.collect::<Vec<_>>(). Đi qua một trình lặp thay vì trả về số Vec trực tiếp có một số lợi thế:

  • split là lười. Điều này có nghĩa rằng nó sẽ không thực sự tách dòng cho đến khi bạn cần nó. Bằng cách đó nó sẽ không lãng phí thời gian tách toàn bộ chuỗi nếu bạn chỉ cần một vài giá trị đầu tiên: split_line.take(2).collect::<Vec<_>>(), hoặc thậm chí nếu bạn chỉ cần giá trị đầu tiên mà có thể được chuyển đổi sang một số nguyên: split_line.filter_map(|x| x.parse::<i32>().ok()).next(). Ví dụ cuối cùng này sẽ không lãng phí thời gian để xử lý "23.0" nhưng sẽ ngừng xử lý ngay lập tức khi nó tìm thấy "1".
  • split không có giả định về cách bạn muốn lưu trữ kết quả.Bạn có thể sử dụng Vec, nhưng bạn cũng có thể sử dụng bất kỳ thứ gì triển khai FromIterator<&str>, ví dụ: LinkedList hoặc VecDeque hoặc bất kỳ loại tùy chỉnh nào triển khai FromIterator<&str>.
+0

Cảm ơn bạn đã trả lời chi tiết của bạn, bất kỳ ý tưởng tại sao 'let x = line.unwrap(). Split (", "). Thu thập :: >();' không hoạt động trừ khi nó được tách thành hai dòng riêng biệt: ' cho x = line.unwrap(); 'và' cho x = x.split (","). thu thập :: >(); '? Thông báo lỗi cho biết: 'giá trị tạm thời được tạo ở đây^giá trị tạm thời bị bỏ ở đây trong khi vẫn mượn ' – Greg

+0

Tuy nhiên nó hoạt động như mong đợi nếu tôi sử dụng' let x = line.as_ref(). Unwrap(). Split (","). :: >(); ' – Greg

Các vấn đề liên quan