Rust提供了一种字符串修整方法:str.trim()删除前导和尾随空格。我想要一种对字节字符串执行相同操作的方法。它应该使用Vec<u8>并删除前导和尾随空格(空格,0x20和htab,0x09)。

编写trim_left()很容易,您可以将迭代器与skip_while()一起使用:Rust Playground

fn main() {
    let a: &[u8] = b"     fo o ";
    let b: Vec<u8> = a.iter().map(|x| x.clone()).skip_while(|x| x == &0x20 || x == &0x09).collect();
    println!("{:?}", b);
}

但是要修剪正确的字符,如果在找到空格后列表中没有其他字母,我将需要向前看。

最佳答案

这是一个返回切片的实现,而不是像Vec<u8>那样返回新的str::trim()的实现。它还在[u8]上实现,因为它比Vec<u8>更通用(您可以廉价地从向量获取切片,但是从切片创建向量的成本更高,因为它涉及堆分配和副本)。

trait SliceExt {
    fn trim(&self) -> &Self;
}

impl SliceExt for [u8] {
    fn trim(&self) -> &[u8] {
        fn is_whitespace(c: &u8) -> bool {
            *c == b'\t' || *c == b' '
        }

        fn is_not_whitespace(c: &u8) -> bool {
            !is_whitespace(c)
        }

        if let Some(first) = self.iter().position(is_not_whitespace) {
            if let Some(last) = self.iter().rposition(is_not_whitespace) {
                &self[first..last + 1]
            } else {
                unreachable!();
            }
        } else {
            &[]
        }
    }
}

fn main() {
    let a = b"     fo o ";
    let b = a.trim();
    println!("{:?}", b);
}

如果确实需要在Vec<u8>之后加上一个trim(),则只需在切片上调用into()即可将其转换为Vec<u8>
fn main() {
    let a = b"     fo o ";
    let b: Vec<u8> = a.trim().into();
    println!("{:?}", b);
}

关于string - 如何实现Vec <u8>的修整?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31101915/

10-12 17:46