我正在处理字符串,需要用一个空格替换多个空格
。看起来大多数都是人为错误,但我对处理这个问题的理想方法很好奇--最好是从&str
到String
的分配最少。
到目前为止这是我下面的做法:
const SPACE: &str = " ";
const TWO_SPACES: &str = " ";
/// Replace multiple spaces with a single space
pub fn trim_whitespace(s: &str) -> String {
let mut new_str: String = s.trim().to_owned();
while new_str.contains(TWO_SPACES) {
new_str = new_str.replace(TWO_SPACES, SPACE);
}
new_str
}
let result = trim_whitespace("Hello world! ");
assert_eq!(result, "Hello world!");
- 编辑(2022年10月)*:我的背景是Python,在Python中做类似上面的事情是非常习惯的。例如,Python中的fastest version(用一个空格替换多个空格)看起来是这样的:
def trim_whitespace(s: str) -> str:
s = s.strip()
while ' ' in s:
s = s.replace(' ', ' ')
return s
2条答案
按热度按时间kokeuurv1#
split_whitespace()
对于这种用法非常方便。在非常简单的第一个解决方案中分配了一个向量和一个字符串。
第二种解决方案只分配一个字符串,但有点不优雅(每次迭代都是
if
)。fae0ux8s2#
你可以使用
split(' ')
,过滤掉空的条目,然后用空格重新连接:另一种可能性是使用
String::retain()
并删除连续的空格。它也应该更快,因为它只分配一次,为修剪的字符串:**编辑:**我很好奇,所以我用字符串
" a bb cc ddd "
对这里建议的所有版本进行了基准测试(当然,不同的字符串会有不同的性能特征)。基准测试代码是here(需要criterion
和itertools
)。结果:
不出所料,您使用
replace()
的版本是最慢的。我使用retain()
和@prog-fh的更快版本是最快的(我期望他的版本会更快,因为它需要复制的更少,但显然差异非常小,现代CPU复制小块内存的速度非常快。也许在更大的字符串中会出现这种情况)。有点令人惊讶的是,使用itertools的join()
的版本比只使用标准库collect()
和join()
的版本要慢,尽管不需要首先收集到一个向量中。(我不确定,但需要检查程序集来验证),更糟糕的是,他们实际上可能需要分配更多的空间,因为他们不知道提前需要的空间量,而且他们还需要插入分隔符。