首页 > 解决方案 > 使用 Rust NOM 解析库迭代多行

问题描述

我正在尝试为 Rust 中的一个项目学习 NOM。我有一个文本文件,其中包括: [tag="#43674"]char[/tag]每行有多个标签背靠背。我正在尝试提取“#43674”和“char”,将它们存储在一个元组中(x, y),然后将它们推送到Vec<(x, y)>文本文件每一行的向量中。到目前为止,我已经成功地将解析器组合成两个函数;一个用于“#43674”,一个用于“char”,然后我将它们组合在一起返回<IResult<&str, (String, String)>。这是代码:

fn color_tag(i: &str) -> IResult<&str, &str> {
    delimited(tag("[color="), take_until("]"), tag("]"))(i)
}

fn char_take(i: &str) -> IResult<&str, &str> {
    terminated(take_until("[/color]"), tag("[/color]"))(i)
}

pub fn color_char(i: &str) -> IResult<&str, (String, String)> {
    let (i, color) = color_tag(i)?;
    let (i, chara) = char_take(i)?;
    let colors = color.to_string();
    let charas = chara.to_string();

    let tuple = (colors, charas);
    
    Ok((i, tuple))
}

如何在文本文件的给定行上迭代此函数?我已经有一个将文本文件迭代成行的函数,但是我需要color_char为该行中的每个闭包重复。我完全错过了重点吗?

标签: rustiterationnom

解决方案


您可能希望nom::multi::many0多次使用组合器来匹配解析器,也可以使用nom::sequence::tuple组合器来组合您的 color_tag 和 char_take 解析器

// Match color_tag followed by char_take
fn color_char(i: &str) -> IResult<&str, (String, String)> {
    tuple((color_tag, char_take))(i)
}

// Match 0 or more times on the same line
fn color_char_multiple(i: &str) -> IResult<&str, Vec<(String, String)>> {
    many0(color_char)(i)
}

要解析多行,您可以修改 color_char() 以将尾随换行符与 nom 提供的字符解析器之一匹配,例如nom::character::complete::line_ending,使用 使其成为可选nom::combinator::opt,并将其与以下内容组合nom::sequence::terminated

terminated(tuple((color_tag, char_take)), opt(line_ending))(i)

推荐阅读