使用 Rust NOM 解析库迭代多行

Iterating over Multiple Lines Using the Rust NOM Parsing Library

我正在尝试为一个 Rust 项目学习 NOM。我有一个包含以下内容的文本文件: [tag="#43674"]char[/tag] 每行有多个背靠背标签。我正在尝试提取“#43674”和 'char',将它们存储在元组 (x, y) 中,然后将它们推入文本文件每一行的向量 Vec<(x, y)> 中。 到目前为止,我已经成功地将解析器组合成两个函数;一个用于“#43674”,一个用于 'char',然后我将它们合并为 return <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 对该行中的每个闭包重复。我是否完全忽略了这一点?

您可能希望使用 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,使用 [= 使其可选15=],并将其与 nom::sequence::terminated:

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