我开始使用Rust了,我正在玩正则表达式箱子以便我可以创建一个词法分析器.
词法分析器使用包含大量命名捕获组的大型正则表达式.我正在尝试获取正则表达式的结果并创建一个Vec<&str, &str>捕获名称和捕获值,但是在映射和过滤结果时迭代返回的值的生命周期一直存在问题.
我认为这与懒惰以及迭代器在超出范围时没有被消耗的事实有关,但我不确定如何真正解决问题.
extern crate regex;
use regex::Regex;
fn main() {
// Define a regular expression with a bunch of named capture groups
let expr = "((?P<num>[0-9]+)|(?P<str>[a-zA-Z]+))";
let text = "0ab123cd";
let re = Regex::new(&expr).unwrap();
let tokens: Vec<(&str, &str)> = re.captures_iter(text)
.flat_map(|t| t.iter_named())
.filter(|t| t.1.is_some())
.map(|t| (t.0, t.1.unwrap()))
.collect();
for token in tokens {
println!("{:?}", token);
}
}
Run Code Online (Sandbox Code Playgroud)
运行上面的代码会导致以下错误:
$ cargo run
Compiling hello_world v0.0.1 (file:///Users/dowling/projects/rust_hello_world)
src/main.rs:14:23: 14:24 error: `t` does not live long enough
src/main.rs:14 .flat_map(|t| t.iter_named())
^
src/main.rs:17:19: 22:2 note: reference must be valid for the block suffix following statement 3 at 17:18...
src/main.rs:17 .collect();
src/main.rs:18
src/main.rs:19 for token in tokens {
src/main.rs:20 println!("{:?}", token);
src/main.rs:21 }
src/main.rs:22 }
src/main.rs:14:23: 14:37 note: ...but borrowed value is only valid for the block at 14:22
src/main.rs:14 .flat_map(|t| t.iter_named())
^~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `hello_world`.
Run Code Online (Sandbox Code Playgroud)
您的情况的限制点是.iter_named()方法:
fn iter_named(&'t self) -> SubCapturesNamed<'t>
Run Code Online (Sandbox Code Playgroud)
请注意&'t self:输出的生命周期将与Captures实例的生命周期相关联.这是因为名称存储在Capture对象中,因此任何名称都&str不能超过此对象.
只有一个解决方法:您必须保持Capture实例活着:
let captures = re.captures_iter(text).collect::<Vec<_>>();
let tokens: Vec<(&str, &str)> = captures.iter()
.flat_map(|t| t.iter_named())
.filter(|t| t.1.is_some())
.map(|t| (t.0, t.1.unwrap()))
.collect();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
217 次 |
| 最近记录: |