假设我想在每个'
将类似于abc'xyz?'zzz'
的字符串拆分为Vec<字符串>,但如果字符前面是?
。我想在没有Regex环视的情况下实现这一点,因为我不能相信输入。
我可以假设,输入是与UTF8兼容的。
在Rust中实现这一点的最快(也可能是最节省内存的方式(是什么?
如果下一个Char是'
,但通过Char比较,当前Char不是?
,我想迭代String并将子字符串保存到var中。然后我将把var的值推到Vec<字符串>通过移动。
这是一个好主意吗?或者有更有效的(时间和记忆方面的(方法来实现这一点吗?
实现这一点的最常用方法是将其作为Iterator
的实现,采用&str
并生成&str
。
这里有一个示例实现,它假设输入字符串上的尾随'
应该而不是在它之后产生一个空元素,空字符串也不应该产生任何元素。请注意,由于我们只处理字符串切片,因此不进行复制。如果您想生成Vec<String>
,那么您可以通过将迭代器映射到str::to_owned
上来实现。(.map(str::to_owned).collect::<Vec<_>>()
(
use std::str::CharIndices;
// A verbose name for an oddly specific concept.
struct SplitStringAtCharNotFollowingCharIterator<'a> {
delimiter: char,
exception: char,
text: &'a str,
chars: CharIndices<'a>,
}
impl<'a> SplitStringAtCharNotFollowingCharIterator<'a> {
pub fn new(text: &'a str, delimiter: char, exception: char) -> Self {
Self { delimiter, exception, text, chars: text.char_indices() }
}
}
impl<'a> Iterator for SplitStringAtCharNotFollowingCharIterator<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<&'a str> {
let first = self.chars.next();
let (start, mut prior) = match first {
None => return None,
Some((_, c)) if c == self.delimiter => return Some(""),
Some(v) => v,
};
loop {
prior = match self.chars.next() {
None => return Some(&self.text[start..]),
Some((end, c)) if c == self.delimiter && prior != self.exception =>
return Some(&self.text[start..end]),
Some((_, c)) => c,
}
}
}
}
(游乐场(
使用它来实现您的既定目标的示例:
let pieces = SplitStringAtCharNotFollowingCharIterator::new("abc'xyz?'zzz'", ''', '?')
.map(str::to_owned)
.collect::<Vec<_>>();
但是,如果您实际上不需要拥有的字符串或向量,您可以直接使用迭代器,因为它会分配原始切片的子切片,所以不需要任何额外的堆分配。
我认为您不需要过度复杂化这一点——一个简单的for循环就可以了。这也可以很容易地准确调整拆分的工作方式,例如包括/排除分隔符、如何处理空匹配。游乐场
fn split(s: &str) -> Vec<String> {
let mut chunks = Vec::new();
let mut cur = String::new();
let mut last_char = None;
for c in s.chars() {
if c == ''' && last_char != Some('?') {
chunks.push(std::mem::take(&mut cur));
} else {
cur.push(c);
}
last_char = Some(c);
}
chunks.push(cur);
chunks
}
如果您想生成Vec<&str>
,您需要做更多的工作来维护对现有字符串的引用,但由于我们返回的是Vec<String>
,我们可以简单地逐个复制字符。