string - 如何为 Vec<u8> 实现修剪?

标签 string arrays rust trim

Rust 为字符串提供了一个 trim 方法: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/

相关文章:

string - 如何找到给定条件描述的所有字符串?

arrays - 在 Swift 中的数组中过滤字典

rust - 对变量的生命周期感到困惑

rust - 使用 Nom 5 解析带有转义引号的单引号字符串

rust - 我可以在静态向量中包含非静态结构吗

python - 为什么lambda函数保持循环最后一步的形式?

java - 给定一个字符串,计算以 'y' 或 'z' 结尾的单词数

c - 在 char* 数组中存储字符串时出错

javascript - 跳过 Javascript 数组中的空格

c - 如何在另一个数组中的用户指定位置插入一个数组并获取结果数组?