高效修剪字符串

rob*_*tex 8 string trim rust

我有一个csv格式的文件,第一列数据表示项目代码,可选择以"UNIUNI"这些字符结尾或混合使用,通过条形码阅读器加载.我需要削减最后一个"UNI"s.

在Rust中,我尝试用部分成功编写一个基本上像这样的函数:

fn main() {
    // Ok: from "9846UNIUNI" to "9846"
    println!("{}", read_csv_rilev("9846UNIUNI".to_string()));

    // Wrong: from "9846uniuni" to "9846"
    println!("{}", read_csv_rilev("9846uniuni".to_string()));
}

fn read_csv_rilev(code: String) -> String {
    code
        //.to_uppercase() /*Unstable feature in Rust 1.1*/
        .trim_right_matches("UNI")
        .to_string()
}
Run Code Online (Sandbox Code Playgroud)

理想的功能签名如下:

fn read_csv_rilev(mut s: &String) {/**/}
Run Code Online (Sandbox Code Playgroud)

但可能对String的就地动作不是一个好主意.实际上,在Rust标准库中没有任何可以做到的事情String::pop().

有没有办法在String上应用修剪而不分配另一个?

She*_*ter 10

一种在String上应用修剪而不分配另一个的方法?

是的,使用truncate:

const TRAILER: &'static str = "UNI";

fn read_csv_rilev(s: &mut String) {
    while s.ends_with(TRAILER) {
        let len = s.len();
        let new_len = len.saturating_sub(TRAILER.len());
        s.truncate(new_len);
    }
}

fn main() {
    let mut code = "Hello WorldUNIUNIUNI".into();

    read_csv_rilev(&mut code);

    println!("{}", code);
}
Run Code Online (Sandbox Code Playgroud)

当然,你根本不需要乱用分配的字符串.您可以使用相同的逻辑并生成字符串的连续子句.这基本上是如何trim_right_matches工作的,但有点不那么通用:

const TRAILER: &'static str = "UNI";

fn read_csv_rilev(mut s: &str) -> &str {
    while s.ends_with(TRAILER) {
        let len = s.len();
        let new_len = len.saturating_sub(TRAILER.len());
        s = &s[..new_len];
    }
    s
}

fn main() {
    let code = "Hello WorldUNIUNIUNI";

    let truncated = read_csv_rilev(code);

    println!("{}", truncated);
}
Run Code Online (Sandbox Code Playgroud)

一般来说,我可能会选择第二种解决方案.


小智 6

我知道这很旧,但是有一个很好的两个衬里,trim_right_matches 现在已弃用,但trim_end_matches() 返回一个 &str ,其中包含您想要的长度

fn read_csv_rilev(code: &mut String) {
        // code.to_uppercase();
        let l = code.trim_end_matches("UNI").len();
        code.truncate(l);
}


Run Code Online (Sandbox Code Playgroud)