如何用nom更优雅提取转义引号间子串及剩余内容?
问题描述
需要从输入字符串"\"Name 1\" something else"(对应实际内容为"Name 1" something else)中提取被双引号包裹的Name 1,同时保留剩余的 something else。当前基于nom库的实现中,手动调用strip_prefix处理闭合引号,认为这一步冗余,希望找到更简洁的实现方式。
当前实现代码:
use nom::bytes::complete::{tag, is_not}; use nom::sequence::pair; use nom::IResult; fn parse_between(i: &str) -> IResult<&str, &str> { let (i, (_o1, o2)) = pair(tag("\""), is_not("\""))(i)?; if let Some(res) = i.strip_prefix("\"") { return Ok((res, o2)); } Ok((i, o2)) } fn main() { println!("{:?}", parse_between("\"Name 1\" something else")); }
代码输出:Ok((" something else", "Name 1"))
优化实现
nom库提供了专门处理前后分隔符包裹内容的delimited组合子,完美适配双引号包裹字符串的场景,可直接替代手动的pair+strip_prefix操作,代码更简洁且符合nom的设计思路:
use nom::bytes::complete::{tag, is_not}; use nom::sequence::delimited; use nom::IResult; fn parse_between(i: &str) -> IResult<&str, &str> { delimited(tag("\""), is_not("\""), tag("\""))(i) } fn main() { println!("{:?}", parse_between("\"Name 1\" something else")); }
说明
delimited(a, b, c)的逻辑是:先通过解析器a匹配开头分隔符,再通过b提取中间目标内容,最后通过c匹配结尾分隔符;最终返回b的解析结果,同时剩余输入自动跳过了首尾分隔符。- 这段代码的输出与原代码完全一致:
Ok((" something else", "Name 1")),但去掉了冗余的strip_prefix判断,逻辑更清晰,也更符合nom库的惯用写法。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

