Rust에서 문자열을 어떻게 분할합니까?


143

로부터 문서 , 그것은 분명하지 않다. Java에서는 다음 split과 같은 방법을 사용할 수 있습니다 .

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


@bow 벡터 대신 String 배열로 만드는 방법이 있습니까?
그렉

나는 적어도 직접적으로 그렇게 할 수있는 방법을 모른다. 아마도 수동으로 반복 Split하고 배열로 설정 해야 할 것입니다 . 물론 이것은 배열의 크기가 고정되어 있고 이전에 배열을 정의해야하므로 각 분할의 항목 수는 같아야합니다. 나는 이것이 단순히을 만드는 것보다 더 문제가 될 수 있다고 생각합니다 Vec.

답변:


158

사용하다 split()

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

반복자 (iterator)를 제공하여 반복하거나 collect()벡터로 만들 수 있습니다 .

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

15
당신은 또한 그것을 쓸 수 있습니다 .collect::<Vec<_>>().
Chris Morgan

결과의 길이는 어떻게 얻 let split습니까? split.len()존재하지 않습니다.
아렉 쿠스

5
@AlexanderSupertramp 사용 .count(). len()소비 할 필요없이 정확한 크기를 알고있는 반복자 전용이며 반복자를 count()소비합니다.
Manishearth

error: cannot borrow immutable local variable
レ ッ ク ス

@AlexanderSupertramp let mut split, 죄송합니다.
Manishearth

53

세 가지 간단한 방법이 있습니다.

  1. 저자 분리기 :

    s.split("separator")  |  s.split('/')  |  s.split(char::is_numeric)
  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());

29

splitstructString 에는 특별한 방법이 있습니다 .

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"]);

14

splitusing : Iterator로 변환 할 수있는를 반환합니다 . 직접 반환하는 대신 반복자를 통과하면 몇 가지 장점이 있습니다.Veccollectsplit_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>.

1
어떤 아이디어는, 상세한 답변을 주셔서 감사합니다 이유는 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 Greg

그러나 내가 사용하면 예상대로 작동합니다.let x = line.as_ref().unwrap().split(",").collect::<Vec<_>>();
Greg

6

또한있다 split_whitespace()

fn main() {
    let words: Vec<&str> = "   foo   bar\t\nbaz   ".split_whitespace().collect();
    println!("{:?}", words);
    // ["foo", "bar", "baz"] 
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.