我有一个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)