You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Rust中用正则表达式捕获单行内的多个复杂元组实例

Rust日志中元组的正则匹配方案

问题场景

需要从如下格式的日志中捕获所有(u64, Option<u64>)格式的元组:

[2025-01-01T08:17:29.791951550Z INFO] Values: [(311154184, Some(389971313710868251)), (311154187, Some(389967898428572732)), (311154182, Some(389971313710868251)), (311154174, Some(389971313710868251)), (311154178, Some(389971313710868251)), (311154197, Some(389811146843151022)), (311154171, Some(389971313710868251)), (311154167, Some(389971313710868251)), (311154185, Some(389967898428572732)), (311154168, Some(389971313710868251)), (311154191, Some(389967898428572732)), (311154196, Some(389811259875653181)), (311154199, Some(0)), (311154192, Some(389967898428572732)), (311154172, Some(389971313710868251)), (311154181, Some(389971313710868251)), (311154177, Some(389971313710868251)), (311154176, Some(389971313710868251)), (311154179, Some(389971313710868251)), (311154183, Some(389971313710868251)), (311154186, Some(389967898428572732)), (311154175, Some(389971313710868251)), (311154173, Some(389971313710868251)), (311154180, Some(389971313710868251)), (311154190, Some(389967898428572732)), (311154170, Some(389971313710868251)), (311154165, None), (311154189, Some(389967898428572732)), (311154169, Some(389971313710868251)), (311154166, None), (311154195, Some(389967898428572732)), (311154198, Some(287087126717485928)), (311154193, Some(389967898428572732)), (311154188, Some(389967898428572732)), (311154194, Some(389967898428572732))]

元组分为两种格式:

  • (311154170, Some(389971313710868251))
  • (311154165, None)

原正则的问题

你之前写的((\((\d+), (Some\((\d+)\)|None\)), )+)存在两个核心问题:

  1. 重复捕获组(+修饰的组)在Rust的regex crate中只会保留最后一次匹配的结果,无法捕获所有元组。
  2. 正则末尾多余的逗号和空格匹配,导致最后一个元组无法被匹配(最后一个元组后无逗号)。

正确的正则表达式

直接匹配单个元组,再通过全局匹配获取所有结果:

\((\d+),\s+(Some\((\d+)\)|None)\)

各部分解释:

  • \(:匹配元组的左括号
  • (\d+):捕获第一个u64类型的数字
  • ,\s+:匹配逗号和任意数量的空白字符(兼容日志中的空格)
  • (Some\((\d+)\)|None):捕获第二个元素,分为两种情况:
    • Some\((\d+)\):匹配Some(数字)格式,其中(\d+)捕获内部的u64数字
    • None:直接匹配None
  • \):匹配元组的右括号

Rust代码实现

  1. 在Cargo.toml中添加依赖:
[dependencies]
regex = "1.10"
  1. 编写解析代码:
use regex::Regex;

fn main() {
    let log_content = r#"[2025-01-01T08:17:29.791951550Z INFO] Values: [(311154184, Some(389971313710868251)), (311154187, Some(389967898428572732)), (311154182, Some(389971313710868251)), (311154174, Some(389971313710868251)), (311154178, Some(389971313710868251)), (311154197, Some(389811146843151022)), (311154171, Some(389971313710868251)), (311154167, Some(389971313710868251)), (311154185, Some(389967898428572732)), (311154168, Some(389971313710868251)), (311154191, Some(389967898428572732)), (311154196, Some(389811259875653181)), (311154199, Some(0)), (311154192, Some(389967898428572732)), (311154172, Some(389971313710868251)), (311154181, Some(389971313710868251)), (311154177, Some(389971313710868251)), (311154176, Some(389971313710868251)), (311154179, Some(389971313710868251)), (311154183, Some(389971313710868251)), (311154186, Some(389967898428572732)), (311154175, Some(389971313710868251)), (311154173, Some(389971313710868251)), (311154180, Some(389971313710868251)), (311154190, Some(389967898428572732)), (311154170, Some(389971313710868251)), (311154165, None), (311154189, Some(389967898428572732)), (311154169, Some(389971313710868251)), (311154166, None), (311154195, Some(389967898428572732)), (311154198, Some(287087126717485928)), (311154193, Some(389967898428572732)), (311154188, Some(389967898428572732)), (311154194, Some(389967898428572732))]"#;

    // 编译正则表达式
    let re = Regex::new(r"\((\d+),\s+(Some\((\d+)\)|None)\)").unwrap();

    // 捕获所有匹配项并转换为目标类型
    let tuples: Vec<(u64, Option<u64>)> = re.captures_iter(log_content)
        .filter_map(|cap| {
            // 解析第一个u64
            let first = cap.get(1)?.as_str().parse().ok()?;
            // 处理第二个元素:Some或None
            let second = match cap.get(2)?.as_str() {
                "None" => None,
                _ => cap.get(3)?.as_str().parse().ok()
            };
            Some((first, second))
        })
        .collect();

    // 打印结果验证
    for tup in tuples {
        println!("{:?}", tup);
    }
}

代码说明

  • captures_iter返回所有匹配的捕获组,遍历每个元组的匹配结果。
  • filter_map处理解析过程中的错误(如数字解析失败),只保留有效元组。
  • 对于Some类型的匹配,通过第三个捕获组获取内部数字;None则直接返回None。

内容的提问来源于stack exchange,提问作者Bobby Dore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:25:54