我有一个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()
}
理想的功能签名如下:
fn read_csv_rilev(mut s: &String) {/**/}
但可能对String的就地动作不是一个好主意。实际上,在Rust标准库中除了String::pop()
之外没有任何事情要做。
有没有办法在String上应用修剪而不分配另一个?
答案 0 :(得分:10)
一种在字符串上应用修剪而不分配另一种方法的方法吗?
是的,使用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);
}
当然,你根本不需要需要来搞乱分配的字符串。您可以使用相同的逻辑并生成字符串的连续子句。这基本上是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);
}
一般来说,我可能会选择第二种解决方案。
答案 1 :(得分:3)
但可能对String的就地操作不是一个好主意。
绑定在mut s: &String
中是可变的,而不是字符串本身。如果你想改变字符串本身,你可以使用s: &mut String
。
那就是说,我认为标准库中没有任何东西可以做到这一点。