这是我的文本:
hello: 3 32 2 8
我想用以下正则表达式捕获它:
^([a-z]+):( [0-9]+)+$
我在做这个:
let txt = "hello: 3 32 2 8";
let re = Regex::new("^([a-z]+):( [0-9]+)+$")?;
let caps = re.captures(txt);
println!("{caps:?}");
我只得到第二个捕获组中的最后一个数字8
:
Some(Captures({0: Some("hello: 3 32 2 8"), 1: Some("hello"), 2: Some(" 8")}))
我怀疑这是captures
的预期行为,但解决方法是什么?
我只需要捕获整个整数序列。由于我们知道这个子字符串具有预期的形状,我们可以放心地对其进行拆分和解析(除非一个整数的位数太多(。
请注意,我在空白处添加了一些公差。
use regex::Regex;
fn detect(txt: &str) -> Result<(&str, Vec<u32>), Box<dyn std::error::Error>> {
let re = Regex::new(r"^s*([a-z]+)s*:((s*[0-9]+)+)s*$")?;
let caps = re.captures(txt).ok_or("no match")?;
// starting from here, we know that all the expected substrings exist
// thus we can unwrap() the options/errors
let name = caps.get(1).unwrap().as_str();
let values = caps
.get(2)
.unwrap()
.as_str()
.split_ascii_whitespace()
.filter_map(|s| s.parse().ok()) // FIXME: overflow ignored
.collect();
Ok((name, values))
}
fn main() {
for txt in [
"hello: 3 32 2 8",
"hello :t3 32 2 8",
"thello :t3 32 2 8 ",
"hello:",
"hello:9999999999 3",
] {
println!("{:?} ~~> {:?}", txt, detect(txt));
}
}
/*
"hello: 3 32 2 8" ~~> Ok(("hello", [3, 32, 2, 8]))
"hello :t3 32 2 8" ~~> Ok(("hello", [3, 32, 2, 8]))
"thello :t3 32 2 8 " ~~> Ok(("hello", [3, 32, 2, 8]))
"hello:" ~~> Err("no match")
"hello:9999999999 3" ~~> Ok(("hello", [3]))
*/