我想实现一个跳过!或!^num位于字符串开头的算法:
fn extract_common_part(a: &str) -> Option<&str> {
let mut it = a.chars();
if it.next() != Some('!') {
return None;
}
let mut jt = it.clone().peekable();
if jt.peek() == Some(&'^') {
it.next();
jt.next();
while jt.peek().map_or(false, |v| !v.is_whitespace()) {
it.next();
jt.next();
}
it.next();
}
Some(it.as_str())
}
fn main() {
assert_eq!(extract_common_part("!^4324 1234"), Some("1234"));
assert_eq!(extract_common_part("!1234"), Some("1234"));
}
Run Code Online (Sandbox Code Playgroud)
这是可行的,但我找不到从Peekableto返回的方法Chars,所以我必须前进it和jt迭代器。这会导致重复代码。
如何从Peekable迭代器返回到相应的Chars迭代器,或者也许有更简单的方法来实现该算法?
简而言之,你不能。一般的答案是使用类似的方法Iterator::by_ref来避免消耗Chars迭代器:
fn extract_common_part(a: &str) -> Option<&str> {
let mut it = a.chars();
if it.next() != Some('!') {
return None;
}
{
let mut jt = it.by_ref().peekable();
if jt.peek() == Some(&'^') {
jt.next();
while jt.peek().map_or(false, |v| !v.is_whitespace()) {
jt.next();
}
}
}
Some(it.as_str())
}
Run Code Online (Sandbox Code Playgroud)
问题是,当您调用peek并且失败时,底层迭代器已经被提前。获取字符串的其余部分将丢失测试为 false 的字符,返回234。
然而,Itertools 有peeking_take_while和take_while_ref,两者都应该可以解决这个问题。
extern crate itertools;
use itertools::Itertools;
fn extract_common_part(a: &str) -> Option<&str> {
let mut it = a.chars();
if it.next() != Some('!') {
return None;
}
if it.peeking_take_while(|&c| c == '^').next() == Some('^') {
for _ in it.peeking_take_while(|v| !v.is_whitespace()) {}
for _ in it.peeking_take_while(|v| v.is_whitespace()) {}
}
Some(it.as_str())
}
Run Code Online (Sandbox Code Playgroud)
其他选项包括:
| 归档时间: |
|
| 查看次数: |
1648 次 |
| 最近记录: |