在Rust中的第一个空格处拆分字符串一次

w46czmvw  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(113)

我有一个字符串,比如"dog cat fish",我想在第一个空格处将其分成两个片段,如下所示:("dog", "cat fish")的值。
我尝试天真地使用split_once()方法,如下所示:

let string = "dog cat fish";
let (first_word, rest_of_string) = string.split_once(' ').unwrap();

字符串
它可以有效地处理常规的空白字符。然而,我希望它也能像split_whitespace()方法一样,对其他类型的Unicode空白字符(如\t)起作用。
我不想使用split_whitespace(),因为它返回一个迭代器,我必须在迭代后重新收集并连接单词,因为这会浪费时间:

let it = string.split_whitespace();
let first_word = it.next().unwrap();
let rest_of_string = it.collect::Vec<&str>().join(" ");


所以,如果我有一个像"dog \t cat fish"这样的字符串,我如何分割它以获得这两个切片("dog", "cat fish")
我也想过使用正则表达式,但有更好的方法吗?
我在寻找一种有效的、可能是惯用的方法。先谢了。

7jmck4yq

7jmck4yq1#

您可以使用一个调用char::is_whitespace()的函数来执行split_once,但这只会在第一个空格处进行拆分。然后需要从一开始修剪第二个&str

fn main() {
    let string = "dog \t cat fish";
    let (a, b) = string.split_once(char::is_whitespace).unwrap();
    let b = b.trim_start();
    dbg!(a, b);
}

字符串
输出量:

[src/main.rs:5] a = "dog"
[src/main.rs:5] b = "cat fish"


Playground

ubof19bj

ubof19bj2#

虽然没有内置的方法,但您可以直接实现它:

fn split_whitespace(s: &str) -> Option<(&str, &str)> {
    let mut iter = s.char_indices();

    let whitespace_start;
    let whitespace_end;

    loop {
        let (pos, ch) = iter.next()?;
        if ch.is_whitespace() {
            whitespace_start = pos;
            break;
        }
    }

    loop {
        let (pos, ch) = iter.next()?;
        if !ch.is_whitespace() {
            whitespace_end = pos;
            break;
        }
    }

    Some((&s[..whitespace_start], &s[whitespace_end..]))
}

fn main() {
    let string = "dog \t\rcat fish";
    println!("{:?}", split_whitespace(string).unwrap());
}

个字符
请注意,没有比迭代其所有字符更快的拆分字符串的方法了,因为Rust字符串中的字符大小是可变的,因为Rust字符串是UTF-8编码的。

相关问题