Rust'da bir dizeyi nasıl bölebilirim?


145

Gönderen belgeler , bu net değil. Java'da şu şekilde splityöntemi kullanabilirsiniz :

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


@bow Bir vektör yerine bir String dizisi yapmanın bir yolu var mı?
Greg

Bunu yapmanın hiçbir şekilde farkında değilim, en azından doğrudan. Muhtemelen üzerinde manuel olarak yineleme yapmanız Splitve diziye ayarlamanız gerekir. Tabii ki bu, diziler sabit boyutta olduğundan ve dizinin daha önce tanımlanmış olması gerektiğinden, her bölmedeki öğe sayısının aynı olması gerektiği anlamına gelir. Bunun sadece bir oluşturmaktan daha fazla sorun olabileceğini hayal ediyorum Vec.
yay

Yanıtlar:


160

kullanım split()

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

Bu, üzerinde veya collect()bir vektörde döngü yapabileceğiniz bir yineleyici verir .

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

15
Ayrıca yazabilirsiniz .collect::<Vec<_>>().
Chris Morgan

sonucun uzunluğunu nasıl alabilirim - let split? split.len()mevcut değil.
ッ ク ス

5
@AlexanderSupertramp Kullanımı .count(). len()yalnızca tüketilmeye gerek kalmadan tam boyutlarını bilen yineleyiciler içindir, yineleyiciyi count()tüketir.
Manishearth

error: cannot borrow immutable local variable mutable olarak bölünmüş
ス レ ッ ク ス

@AlexanderSupertramp let mut split, üzgünüm.
Manishearth

53

Üç basit yol vardır:

  1. By ayırıcı :

    s.split("separator")  |  s.split('/')  |  s.split(char::is_numeric)
  2. By boşluk :

    s.split_whitespace()
  3. Yeni satırlara göre :

    s.lines()

Her türün sonucu bir yineleyicidir:

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

29

splitYapı içinString özel bir yöntem vardır :

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

Karakterle böl:

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

Dizeye göre böl:

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

Kapanışla böl:

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

14

splitkullanarak Iteratorbir dönüştürebilirsiniz : döndürür . Doğrudan döndürmek yerine yineleyiciden geçmenin birkaç avantajı vardır:Veccollectsplit_line.collect::<Vec<_>>()Vec

  • splittembeldir. Bu, hattı ihtiyacınız olana kadar gerçekten bölmeyeceği anlamına gelir. Bu şekilde, yalnızca ilk birkaç değere split_line.take(2).collect::<Vec<_>>()ihtiyacınız varsa ya da yalnızca bir tamsayıya dönüştürülebilen ilk değere ihtiyacınız olsa bile, dizenin tamamını bölmek için zaman kaybetmezsiniz split_line.filter_map(|x| x.parse::<i32>().ok()).next(). Bu son örnek, "23.0" ı işlemek için zaman kaybetmez, ancak "1" i bulduktan hemen sonra işlemi durdurur.
  • splitsonucu saklamak istediğiniz yolla ilgili hiçbir varsayımda bulunmaz. A kullanabilirsiniz Vecancak uygulayan her şeyi FromIterator<&str>, örneğin a LinkedListveya a VecDequeveya uygulayan herhangi bir özel türü de kullanabilirsiniz FromIterator<&str>.

1
Ayrıntılı yanıtınız için teşekkür ederiz, let x = line.unwrap().split(",").collect::<Vec<_>>();iki ayrı satıra ayrılmadıkça neden işe yaramadığına dair herhangi bir fikir : let x = line.unwrap();ve let x = x.split(",").collect::<Vec<_>>();? Hata mesajı:temporary value created here ^ temporary value dropped here while still borrowed
Greg

Ancak ben kullanırsam beklendiği gibi çalışırlet x = line.as_ref().unwrap().split(",").collect::<Vec<_>>();
Greg

6

Ayrıca split_whitespace()

fn main() {
    let words: Vec<&str> = "   foo   bar\t\nbaz   ".split_whitespace().collect();
    println!("{:?}", words);
    // ["foo", "bar", "baz"] 
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.