如何用Rust以惯用方式捕获字符串中所有数字并返回整数向量?
Rust惯用实现:从字符串提取所有整数并返回
Vec<isize> 我来帮你修正这个函数,先聊聊你现有代码里的几个问题:
- 返回类型不匹配:需求是返回
Vec<isize>,但你写的是Vec<String> - 匹配逻辑不对:
captures只会返回第一个匹配的捕获结果,没法拿到所有数字 - 缺少结果收集和类型转换:你没有把匹配到的字符串转成整数,也没把结果收集成向量
下面是符合Rust惯用写法的正确实现:
首先,你需要在Cargo.toml里添加依赖:
[dependencies] regex = "1.10" lazy_static = "1.4"
然后是函数代码:
use regex::Regex; use lazy_static::lazy_static; fn str_strip_numbers(s: &str) -> Vec<isize> { // 懒加载正则表达式:整个程序生命周期只编译一次,避免重复编译开销 lazy_static! { static ref NUMBER_REGEX: Regex = Regex::new(r"\d+") .expect("Failed to compile number matching regex"); } NUMBER_REGEX.find_iter(s) // 把每个匹配结果转换成字符串切片 .map(|match_result| match_result.as_str()) // 将字符串解析为isize:因为正则匹配的是纯数字,所以解析不会失败,用unwrap安全 .map(|num_str| num_str.parse::<isize>().unwrap()) // 把迭代器收集成目标向量 .collect() }
测试用例验证
你可以用这些测试确保功能符合预期:
fn main() { // 无数字场景 assert_eq!(str_strip_numbers("alfa"), Vec::<isize>::new()); // 分散数字场景 assert_eq!(str_strip_numbers("42by4"), vec![42, 4]); // 多组连续数字场景 assert_eq!(str_strip_numbers("123test456xyz789"), vec![123, 456, 789]); }
简化版本(不需要全局缓存)
如果你的函数不会被频繁调用,也可以去掉lazy_static,每次调用时编译正则(性能略差,但代码更简洁):
use regex::Regex; fn str_strip_numbers(s: &str) -> Vec<isize> { let number_regex = Regex::new(r"\d+").expect("Regex compilation failed"); number_regex.find_iter(s) .map(|m| m.as_str().parse().unwrap()) .collect() }
关键细节说明
find_iter:这个方法会返回字符串中所有匹配正则的结果迭代器,正好满足我们提取所有数字的需求lazy_static:用于全局缓存编译后的正则表达式,避免每次调用函数都重新编译,这是Rust中处理全局正则的惯用方式- 类型转换:因为我们用
\d+匹配的是纯数字字符串,所以parse::<isize>不会失败,用unwrap是安全的;如果需要处理极端情况(比如数字超出isize范围),可以改用match或unwrap_or_else来处理解析错误
内容的提问来源于stack exchange,提问作者Alexey Orlov
相关产品推荐
相关产品推荐

