如何在nom中构建负向前瞻解析器?
用nom实现负向前瞻解析器
要实现解析hello但排除其后紧跟 world的场景(对应正则hello(?! world)),你原代码的问题在于cond的第一个参数要求是布尔值,但peek(not(tag(" world")))返回的是IResult类型,类型不匹配导致无法运行。
正确的做法是利用nom的组合子特性,通过peek、not和preceded来实现负向前瞻:
use nom::{ bytes::complete::tag, combinator::{not, peek}, sequence::preceded, IResult, }; fn hello_not_followed_by_world(input: &str) -> IResult<&str, &str> { // 先做负向前瞻断言:当前位置后不跟着" world" // 再解析"hello",并返回该解析结果 preceded(peek(not(tag(" world"))), tag("hello"))(input) }
代码说明
peek(not(tag(" world"))):peek会检查当前输入后续内容但不消耗输入;not(tag(" world"))会在后续内容匹配" world"时失败,未匹配时成功,二者结合实现了"后面不是指定内容"的负向前瞻断言。preceded组合子会先执行前置的断言解析器,成功后再执行目标解析器(tag("hello")),最终返回目标解析器的结果。
测试示例
- 输入
"hello":解析成功,返回Ok(("", "hello")) - 输入
"hello world":断言失败,解析报错 - 输入
"helloworld":断言通过,解析成功,返回Ok(("world", "hello"))
内容的提问来源于stack exchange,提问作者mdcq
相关产品推荐
相关产品推荐

