题 如何在Rust中拆分字符串?


来自 文件,目前尚不清楚。在Java中你可以使用 split 像这样的方法:

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

58
2017-10-30 01:45


起源


doc.rust-lang.org/std/string/struct.String.html - Dulguun Otgon
@bow有没有办法让它成为一个String数组而不是一个向量? - Greg
我至少直接知道没有办法做到这一点。你可能不得不手动迭代 Split 并将其设置为数组。当然,这意味着每个拆分中的项目数必须相同,因为数组是固定大小的,您必须先定义数组。我想这可能比创建一个更麻烦 Vec。 - bow


答案:


使用 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();

75
2017-10-30 02:00



你也可以写它 .collect::<Vec<_>>()。 - Chris Morgan
如何获得结果的长度 - let split? split.len() 不存在。 - アレックス
@AlexanderSupertramp使用 .count()。 len() 仅适用于知道其确切大小而无需使用的迭代器, count() 使用迭代器。 - Manishearth
error: cannot borrow immutable local variable 分裂为可变的` - アレックス
@AlexanderSupertramp let mut split对不起 - Manishearth


有一种特殊的方法 split 对于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"]);

16
2018-05-06 19:57





有三种简单的方法:

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

12
2017-07-01 06:59





split 返回一个 Iterator,你可以转换成一个 Vec 运用 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>,例如a LinkedList 或者a VecDeque,或任何实现的自定义类型 FromIterator<&str>

5
2017-11-07 07:39



感谢您的详细解答,任何想法为什么 let x = line.unwrap().split(",").collect::<Vec<_>>(); 除非它被分成两个单独的行,否则不起作用: let x = line.unwrap(); 和 let x = x.split(",").collect::<Vec<_>>();?错误消息说: temporary value created here ^ temporary value dropped here while still borrowed - Greg
但是,如果我使用它,它会按预期工作 let x = line.as_ref().unwrap().split(",").collect::<Vec<_>>(); - Greg


还有 split_whitespace()

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

4
2018-04-27 03:41