微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何匹配正则表达式但在 Rust Nom 中返回输入的剩余部分?

如何解决如何匹配正则表达式但在 Rust Nom 中返回输入的剩余部分?

我正在尝试使用 Nom 6.1.2 来解析一种相对简单的 Lisp 之类的语言,我需要在其中捕获 [a-z][a-zA-Z0-9_\-\.] 形式的标识符。我尝试使用 re_match 但这期望整个 input 不仅匹配字符串的第一部分。我希望能够将这些标识符作为更大上下文的一部分进行匹配,因此我希望它返回输入的其余部分,以解析器组合器的方式传递给其他解析器。

fn name(input: &str) -> IResult<&str,&str,VerboseError<&str>> {
    let re = Regex::new(r"^[A-Za-z][a-zA-Z0-9_\.\-]*$").unwrap();
    context("name",re_match(re))(input)
}

我希望通过的测试如下:

#[test]
fn test_name() {
    assert_eq!(name("test"),Ok(("","test")));
    assert_eq!(name("test1-test2"),"test1-test2")));
    assert_eq!(name("test1.test2"),"test1.test2")));
    assert_eq!(name("test1_test2"),"test1_test2")));
    assert_eq!(name("Test1_Test2"),"Test1_Test2")));
    assert!(name("123Test").is_err());

    //this last assertion fails
    assert_eq!(name("test1 test2$!%"),Ok((" test2$!%","test1")));
}

上述测试中的最后一个断言失败。

thread 'parser::tests::test_name' panicked at 'assertion Failed: `(left == right)`
  left: `Err(Error(VerboseError { errors: [("test1 test2$!%",Nom(RegexpMatch)),("test1 test2$!%",Context("name"))] }))`,right: `Ok((" test2$!%","test1"))`',src\parser.rs:69:9
stack backtrace:

如果我使用的是 alphanumeric 之类的函数,这会正常工作,但这不会捕获我想要的正则表达式。

我可以自己编写代码并以某种方式检查第一个字符和随后的字符,但是我还有其他几种情况需要解析不同的正则表达式,并且它将变得无法维护。

获取与正则表达式匹配的部分并继续解析较大输入的其余部分的正确方法是什么?

解决方法

我试过了,部分问题出在正则表达式末尾的 $ 上。这将告诉正则表达式匹配器匹配整个输入直到结束,否则将不匹配。

另一个问题是 re_match()。从 nom 文档中,如果找到匹配项, re_match 将返回整个输入(无论匹配多少个字符)。您想要的是 re_find() 函数,它将返回第一个匹配项。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。