8 个版本

0.6.2 2024年3月31日
0.5.3 2024年3月7日
0.4.0 2023年12月31日
0.3.1 2023年8月16日
0.0.1 2023年7月30日

#439解析器实现

Download history 2/week @ 2024-04-14 7/week @ 2024-04-21 3/week @ 2024-04-28 4/week @ 2024-05-05 1/week @ 2024-05-12 14/week @ 2024-05-19 1/week @ 2024-05-26 7/week @ 2024-06-02 5/week @ 2024-06-09 9/week @ 2024-06-16 6/week @ 2024-06-23 60/week @ 2024-06-30 8/week @ 2024-07-28

61 每月下载量
3 个 crate 中使用 (通过 aopt)

MPL-2.0 许可协议

380KB
10K SLoC

neure

一个快速的小型组合解析库

为什么选择 neure

  • 更好的性能

  • 更少的依赖

  • 更快的编译速度

示例

更多示例,请参考 examples

示例 1

use neure::prelude::*;

pub fn main() -> Result<(), Box<dyn std::error::Error>> {
    let year = re!(['0' - '9']+); // match digit from 0 to 9 more than once
    let year = year.map(map::from_str::<i32>()); // map it to i32
    let name = neu::ascii_alphabetic().repeat_one_more(); // match ascii alphabetic
    let mut ctx = CharsCtx::new("2024rust");

    // .then construct a tuple
    assert_eq!(ctx.ctor(&year.then(name))?, (2024, "rust"));
    Ok(())
}

crate regex 的代码比较

mod neure_ {
    use neure::prelude::*;

    fn parser(str: &str) -> Result<(), neure::err::Error> {
        let mut ctx = RegexCtx::new(str);
        let alpha = neu::range('a'..='z');
        let num = neu::digit(10);
        let name = neu!((alpha, num, '_', '.', '+', '-')).repeat_one_more();
        let domain = alpha.or(num).or('.').or('-').repeat_to::<256>().set_cond(
            |ctx: &CharsCtx, item: &(usize, char)| {
                // stop at last '.'
                Ok(!(item.1 == '.' && ctx.orig_at(ctx.offset() + item.0 + 1)?.find('.').is_none()))
            },
        );
        let email = re::start()
            .then(name)
            .then("@")
            .then(domain)
            .then(".")
            .then(neu!((alpha, '.')).repeat::<2, 6>())
            .then(re::end());

        ctx.try_mat(&email)?;
        Ok(())
    }

    pub fn parse(tests: &[&str], results: &[bool]) {
        for (test, result) in tests.iter().zip(results.iter()) {
            assert_eq!(parser(test).is_ok(), *result, "test = {}", test);
        }
    }
}

mod regex_ {
    use regex::Regex;

    pub fn parse(re: &Regex, tests: &[&str], results: &[bool]) {
        for (test, result) in tests.iter().zip(results.iter()) {
            assert_eq!(re.is_match(test), *result);
        }
    }
}

fn main() -> color_eyre::Result<()> {
    color_eyre::install()?;

    let test_cases = [
        "plainaddress",
        "#@%^%#$@#$@#.com",
        "@example.com",
        "joe smith <[email protected]>",
        "”(),:;<>[ ]@example.com",
        "much.”more unusual”@example.com",
        "very.unusual.”@”[email protected]",
        "[email protected]",
        "[email protected]",
        "[email protected]",
    ];
    let results = [
        false, false, false, false, false, false, false, true, true, true,
    ];
    let re: regex::Regex =
        regex::Regex::new(r"^([a-z0-9_\.\+-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$").unwrap();

    regex_::parse(&re, &test_cases, &results);
    neure_::parse(&test_cases, &results);

    Ok(())
}

许可证

MPL-2.0

依赖项