2

我想编写一个 nom 解析器组合器,它需要尽可能多的字节,包括标签序列。我尝试使用take_until_and_consume!,但我发现生成的解析器组合器丢弃了标记序列:

#[macro_use]
extern crate nom;

named!(up_to_and_including_backslash, take_until_and_consume!("\\"));

fn main() {
    let res = up_to_and_including_backslash(b"    \\");
    println!("{:?}", res);
}

结果是:

Done([], [32, 32, 32, 32])

我想要的是将标签序列(在本例中为反斜杠字符)包含在结果中:

Done([], [32, 32, 32, 32, 92])

我怎样才能做到这一点?

4

2 回答 2

2

更新:
您想使用recognize!ontake_until_and_consume!("\\")将它消耗的所有内容添加到输出中。

你会这样写你的解析器函数:

#[macro_use]
extern crate nom;

named!(up_to_and_including_backslash, recognize!( take_until_and_consume!("\\") ));

fn main() {
    let res = up_to_and_including_backslash(b"    \\");
    println!("{:?}", res);
}

如果您需要将多个解析器的消耗符号包含到您的输出中,您可以将它们全部放在一个 insidedo_parse!recognize!。像这样:

recognize!( do_parse!( tag!("\\") >> take_until_and_consume!("\\") >> take!(4) >> () ) )

旧:
我让它工作的唯一方法就是这个丑陋的可憎之物。

named!(up_to_and_including_backslash,
    do_parse!(
        line: take_until_and_consume!("\\") >>
        (
            { 
                let mut complete_line:Vec<u8> = line.to_vec();
                complete_line.extend_from_slice(b"\\");
                &*complete_line
            }
        )
    )
);
于 2018-04-06T02:21:04.897 回答
-1

现在您正在使用take_until_and_consume文档中说的方法:

生成一个解析器消耗字节直到找到指定的字节序列,并消耗它

消耗部分很重要,因为它是您要避免的。

你可以做类似这样的事情:

named!(up_to_and_including_backslash,
    do_parse!(
        line: take_until!("\\") >> char!('\\') >>
        (line)
    )
);

哪个应该返回带有分隔符的行。

于 2017-11-24T11:57:48.283 回答