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

How to match regular expression but return the remaining part of the input in Rust Nom?

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

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"), Ok(("", "test1-test2")));
    assert_eq!(name("test1.test2"), Ok(("", "test1.test2")));
    assert_eq!(name("test1_test2"), Ok(("", "test1_test2")));
    assert_eq!(name("Test1_Test2"), Ok(("", "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 将 return 整个输入(无论匹配了多少个字符)。您想要的是 re_find() 函数,它将 return 第一个匹配项。