6. 重复解析器

重复谓词的单个解析器很有用,但更有用的是重复解析器的组合器。Nom 有多个按照这一原则运行的组合器;其中最明显的是 many0 ,它尽可能多地应用解析器;并返回这些解析结果的向量。这是一个例子:

extern crate nom;
use std::error::Error;
use nom::IResult;
use nom::multi::many0;
use nom::bytes::complete::tag;

fn parser(s: &str) -> IResult<&str, Vec<&str>> {
  many0(tag("abc"))(s)
}

fn main() {
    assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"])));
    assert_eq!(parser("abc123"), Ok(("123", vec!["abc"])));
    assert_eq!(parser("123123"), Ok(("123123", vec![])));
    assert_eq!(parser(""), Ok(("", vec![])));
}

有许多不同的解析器可供选择:

组合子用法输入输出注释
countopen in new windowcount(take(2), 3)"abcdefgh"Ok(("gh", vec!["ab", "cd", "ef"]))将子解析器应用指定次数
many0open in new windowmany0(tag("ab"))"abababc"Ok(("c", vec!["ab", "ab", "ab"]))将解析器应用 0 次或更多次,并返回结果列表。many1 做同样的事情,但必须返回至少一个元素
many_m_nopen in new windowmany_m_n(1, 3, tag("ab"))"ababc"Ok(("c", vec!["ab", "ab"]))将解析器应用在 m 和 n 次之间(包括 n),并返回结果列表
many_tillopen in new windowmany_till(tag("ab"), tag("ef"))"ababefg"Ok(("g", (vec!["ab", "ab"], "ef")))将第一个解析器应用到第二个解析器应用为止。返回一个包含第一个解析器结果列表和第二个解析器结果的元组
separated_list0open in new windowseparated_list0(tag(","), tag("ab"))"ab,ab,ab."Ok((".", vec!["ab", "ab", "ab"]))separated_list1 的工作方式与 separated_list0 类似,但必须返回至少一个元素
fold_many0open in new window`fold_many0(be_u8,0,acc, item
fold_many_m_nopen in new window`fold_many_m_n(1, 2, be_u8,0,acc, item
length_countopen in new windowlength_count(number, tag("ab"))"2ababab"Ok(("ab", vec!["ab", "ab"]))从第一个解析器获取一个数字,然后应用第二个解析器该次数
Last Updated 2024-11-28 11:45:01