I have a file in the CSV format with a first column of data that represents item code optionally ended with "UNIUNI"
or mixed case of these chars, loaded by means of a barcode reader. I need to trim away the last "UNI"
s.
I wrote this function:
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()
}
The ideal function signature looks like:
fn read_csv_rilev(mut s: &String)
but probably an in-place action on a String
is not a good idea. In fact, in the Rust standard library there isn't anything to do this excluding String::pop()
.
The trim() method in Java String is a built-in function that eliminates leading and trailing spaces. The Unicode value of space character is '\u0020'. The trim() method in java checks this Unicode value before and after the string, if it exists then removes the spaces and returns the omitted string.
trim() The trim() method removes whitespace from both ends of a string and returns a new string, without modifying the original string.
The trimming string means removing whitespaces from left and right part of the string. To trim the C++ string, we will use the boost string library. In that library, there are two different methods called trim_left() and trim_right(). To trim string completely, we can use both of them.
Is there a way to trim a
String
without allocating another one?
Yes, you can use truncate
to remove trailing parts of the string:
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);
assert_eq!("Hello World", code);
}
You don't need to mess with the allocated string at all. You can use the same logic and make successive subslices of the string. This is basically how trim_right_matches
works, but a bit less generic:
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);
assert_eq!("Hello World", truncated);
}
In general, I'd probably go with the second solution.
I know this is old, but there is a nice two liner, trim_right_matches is deprecated now, but trim_end_matches() returns a &str with the length you want
fn read_csv_rilev(code: &mut String) {
// code.to_uppercase();
let l = code.trim_end_matches("UNI").len();
code.truncate(l);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With