Comment puis-je diviser une chaîne dans Rust?

De la documentation , ce n'est pas clair. En Java, vous pouvez utiliser la méthode split comme ceci:

"some string 123 ffd".split("123");
59
demandé sur maxcountryman 2014-10-30 04:45:31

5 réponses

Utiliser split()

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

Cela donne un itérateur, que vous pouvez boucler, ou collect() dans un vecteur.

for s in split {
    println!("{}", s)
}
let vec = split.collect::<Vec<&str>>();
// OR
let vec: Vec<&str> = split.collect();
76
répondu Manishearth 2016-12-21 23:43:58

Il y a une méthode spéciale split pour les struct String:

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

Divisé par caractère:

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

Divisé par chaîne:

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

Divisé par fermeture:

let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
assert_eq!(v, ["abc", "def", "ghi"]);
17
répondu Denis Kreshikhin 2016-12-21 23:44:31

Il y a trois façons simples:

  1. Par séparateur:

    s.split("separator")
    
  2. Par espaces:

    s.split_whitespace()
    
  3. Par nouvelles lignes :

    s.lines()
    

Le résultat de chaque type est un itérateur:

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());
13
répondu DenisKolodin 2016-12-21 23:46:29

split retourne un Iterator, que vous pouvez convertir en un Vec à l'aide de collect: split_line.collect::<Vec<_>>(). Passer par un itérateur au lieu de retourner un Vec A directement plusieurs avantages:

  • split est paresseux. Cela signifie qu'il ne sera pas vraiment diviser la ligne jusqu'à ce que vous en ayez besoin. De cette façon, il ne perdra pas de temps à diviser la chaîne entière si vous n'avez besoin que des premières valeurs: split_line.take(2).collect::<Vec<_>>(), ou même si vous n'avez besoin que de la première valeur pouvant être convertie en entier: split_line.filter_map(|x| x.parse::<i32>().ok()).next(). Ce dernier l'exemple ne perdra pas de temps à essayer de traiter le "23.0" mais arrêtera le traitement immédiatement une fois qu'il trouvera le "1".
  • split ne fait aucune hypothèse sur la façon dont vous voulez stocker le résultat. Vous pouvez utiliser un Vec, mais vous pouvez également utiliser quoi que ce soit qui met en œuvre FromIterator<&str>, par exemple, un LinkedList ou un VecDeque, ou tout autre type qui implémente FromIterator<&str>.
5
répondu Jmb 2017-11-07 13:50:54

Il y a aussi split_whitespace()

fn main() {
    let words: Vec<&str> = "   foo   bar\t\nbaz   ".split_whitespace().collect();
    println!("{:?}", words);
    // ["foo", "bar", "baz"] 
}
4
répondu jayelm 2016-04-27 03:41:01