rust - Rust Nom:输入的多和结尾
问题描述
我正在尝试熟悉 Nom,目前是第 5 版,其中没有CompleteStr
其他内容,因此相关问题没有太大帮助。
我怎样才能解析类似的东西
"@pook Some free text @another_pook And another text"
进入
vec![("pook", "Some free text"), ("another_pook", "And another text")]
?
@
前置字符串称为“字段标识符”;下一个子字符串是描述;两者都称为“场”
这是我成功解析一个字段的方法:
use nom::bytes::complete::take_while1;
use nom::*;
use nom::character::is_alphabetic;
fn ident(c: char) -> bool {
is_alphabetic(c as u8) || c == '_'
}
fn freetext(c: char) -> bool {
c != '@'
}
fn parse_ident(s: &str) -> IResult<&str, &str> {
take_while1(ident)(s)
}
fn parse_freetext(s: &str) -> IResult<&str, &str> {
take_while1(freetext)(s)
}
named! {field_ident<&str, &str>,
do_parse!(
tag!("@") >>
name: parse_ident >>
(name)
)
}
named! { field <&str, (&str, &str)>,
do_parse!(
name: ws!(field_ident) >>
description: parse_freetext >>
(name, description)
)
}
当我按照开头所述将其包装many1
并提供输入时,我收到了Err(Incomplete(Size(1)))
,但是如果我将其放在@
输入的末尾,它就可以工作。如何在输入结束时将其标记为已完成?
解决方案
You want many_till
combinator, not many1
, like so:
use nom::bytes::complete::take_while1;
use nom::character::is_alphabetic;
use nom::*;
fn ident(c: char) -> bool {
is_alphabetic(c as u8) || c == '_'
}
fn freetext(c: char) -> bool {
c != '@'
}
fn parse_ident(s: &str) -> IResult<&str, &str> {
take_while1(ident)(s)
}
fn parse_freetext(s: &str) -> IResult<&str, &str> {
take_while1(freetext)(s)
}
named! {field_ident<&str, &str>,
do_parse!(
tag!("@") >>
name: parse_ident >>
(name)
)
}
named! { field <&str, (&str, &str)>,
do_parse!(
name: ws!(field_ident) >>
description: parse_freetext >>
(name, description)
)
}
named!(fields<&str, (Vec<(&str, &str)>, &str)>, many_till!(field, eof!()));
fn main() {
println!("{:?}", field("@pook Some free text"));
println!(
"{:?}",
fields("@pook Some free text @another_pook And another text")
);
}
Rather counter-intuitive. It has to do with the streaming nature of nom
, I guess.
推荐阅读
- android - Flutter:如果我想导航到详细信息页面,我会得到无效的参数
- apache-kafka - 无法将大文件发送到 Kafka 代理 | 错误消息:请求包含的消息大于服务器将接受的最大消息大小
- django - 如何使用 Django 中内置的 EmailValidator 验证 UserCreationForm 的电子邮件字段?
- powershell - 使用 ews 删除电话号码
- windows - 如何在win10中创建在后台而不是前台运行命令的热键?
- c++ - 在 C++ 中,在对象内分配多个数据时,堆栈分配是否更有效?A_Heap 类在下面的程序中效率会降低吗?
- json - 加载json文件,删除字符,输出新的json文件
- c - 如何获得由 pthread 运行的函数的返回值?
- php - 如何在具有 id 的特定 div 中获取 ajax 响应
- c++ - 通过使用 C++ 获取输入和输出的 TFLite 分段错误