使用 Rust NOM 解析库迭代多行

ZU4*_*420 4 iteration 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))
}
Run Code Online (Sandbox Code Playgroud)

如何在文本文件的给定行上迭代此函数?我已经有一个将文本文件迭代为行的函数,但我需要color_char对该行中的每个闭包重复该操作。我完全没有抓住重点吗?

tra*_*tor 5

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

// Match color_tag followed by char_take
fn color_char(i: &str) -> IResult<&str, (&str, &str)> {
    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)
}
Run Code Online (Sandbox Code Playgroud)

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

terminated(tuple((color_tag, char_take)), opt(line_ending))(i)
Run Code Online (Sandbox Code Playgroud)