You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:15:28