如何实现不跳过标签的 take_until_and_consume-like 解析器组合器?
How to implement a take_until_and_consume-like parser combinator that does not skip the tag?
我想编写一个 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])
我怎样才能做到这一点?
现在您正在使用 take_until_and_consume
方法,其文档说明:
generates a parser consuming bytes until the specified byte sequence
is found, and consumes it
消费部分很重要,因为这是您要避免的。
你可以做类似这样的事情:
named!(up_to_and_including_backslash,
do_parse!(
line: take_until!("\") >> char!('\') >>
(line)
)
);
哪一行应该 return 与您的分隔符。
更新:
您想在 take_until_and_consume!("\")
上使用 recognize!
将它消耗的所有内容添加到输出。
您可以这样编写解析器函数:
#[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);
}
如果您需要将多个解析器使用的符号包含到您的输出中,您可以将它们全部放在 recognize!
内的 do_parse!
中。像这样:
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
}
)
)
);
我想编写一个 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])
我怎样才能做到这一点?
现在您正在使用 take_until_and_consume
方法,其文档说明:
generates a parser consuming bytes until the specified byte sequence is found, and consumes it
消费部分很重要,因为这是您要避免的。
你可以做类似这样的事情:
named!(up_to_and_including_backslash,
do_parse!(
line: take_until!("\") >> char!('\') >>
(line)
)
);
哪一行应该 return 与您的分隔符。
更新:
您想在 take_until_and_consume!("\")
上使用 recognize!
将它消耗的所有内容添加到输出。
您可以这样编写解析器函数:
#[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);
}
如果您需要将多个解析器使用的符号包含到您的输出中,您可以将它们全部放在 recognize!
内的 do_parse!
中。像这样:
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
}
)
)
);