我找到了这个替换子字符串的例子:
use std::str;
let string = "orange";
let new_string = str::replace(string, "or", "str");
Run Code Online (Sandbox Code Playgroud)
如果我想在同一个字符串上运行多个连续替换,为了清理目的,如何在不为每个替换分配新变量的情况下执行此操作?
如果您要编写惯用的Rust,您将如何编写多个链式子串替换?
Tim*_*mmm 10
我不会为此使用正则表达式 or .replace().replace().replace()or 。.maybe_replace().maybe_replace().maybe_replace()他们都有很大的缺陷。
.replace().replace().replace()由于显而易见的原因,这很糟糕。.maybe_replace().maybe_replace().maybe_replace()仅比这稍好一些,因为它仅在模式不匹配时提高效率。如果它们全部匹配,它不会避免重复分配,在这种情况下,它实际上更糟糕,因为它会搜索字符串两次。有一个更好的解决方案:使用Aho-Corasick crate。自述文件中甚至还有一个示例:
use aho_corasick::AhoCorasick;
let patterns = &["fox", "brown", "quick"];
let haystack = "The quick brown fox.";
let replace_with = &["sloth", "grey", "slow"];
let ac = AhoCorasick::new(patterns);
let result = ac.replace_all(haystack, replace_with);
assert_eq!(result, "The slow grey sloth.");
Run Code Online (Sandbox Code Playgroud)
用于消毒目的
我还应该说,将“坏”字符串列入黑名单是完全错误的清理方法。
您将如何编写多个链接的子字符串替换?
我会按照要求去做:
fn main() {
let a = "hello";
let b = a.replace("e", "a").replace("ll", "r").replace("o", "d");
println!("{}", b);
}
Run Code Online (Sandbox Code Playgroud)
如果您问的是如何进行多个并发替换,只通过一次字符串,那么它确实变得更加困难。
这确实需要为每次replace调用分配新的内存,即使不需要替换。的替代实现replace可能会返回 a Cow<str>,它仅在发生替换时包含拥有的变体。一个hacky实现可能看起来像:
use std::borrow::Cow;
trait MaybeReplaceExt<'a> {
fn maybe_replace(self, needle: &str, replacement: &str) -> Cow<'a, str>;
}
impl<'a> MaybeReplaceExt<'a> for &'a str {
fn maybe_replace(self, needle: &str, replacement: &str) -> Cow<'a, str> {
// Assumes that searching twice is better than unconditionally allocating
if self.contains(needle) {
self.replace(needle, replacement).into()
} else {
self.into()
}
}
}
impl<'a> MaybeReplaceExt<'a> for Cow<'a, str> {
fn maybe_replace(self, needle: &str, replacement: &str) -> Cow<'a, str> {
// Assumes that searching twice is better than unconditionally allocating
if self.contains(needle) {
self.replace(needle, replacement).into()
} else {
self
}
}
}
fn main() {
let a = "hello";
let b = a.maybe_replace("e", "a")
.maybe_replace("ll", "r")
.maybe_replace("o", "d");
println!("{}", b);
let a = "hello";
let b = a.maybe_replace("nope", "not here")
.maybe_replace("still no", "i swear")
.maybe_replace("but no", "allocation");
println!("{}", b);
assert_eq!(b.as_ptr(), a.as_ptr());
}
Run Code Online (Sandbox Code Playgroud)
在正则表达式引擎可以用来做字符串替换多个单传,但我会感到惊讶,如果这实际上是更好的性能:
extern crate regex;
use regex::{Captures, Regex};
fn main() {
let re = Regex::new("(or|e)").unwrap();
let string = "orange";
let result = re.replace_all(string, |cap: &Captures| {
match &cap[0] {
"or" => "str",
"e" => "er",
_ => panic!("We should never get here"),
}.to_string()
});
println!("{}", result);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
888 次 |
| 最近记录: |