如何简化返回nom解析器的函数中的参数模板编写?
解决Nom中&str未实现UnspecializedInput的编译错误,实现引号字符串解析
错误原因
你添加的UnspecializedInput约束是Nom的内部标记 trait,仅用于Nom区分"无专门优化实现"的输入类型。而&str作为Nom的核心输入类型,有专门的优化实现,因此不会实现这个trait,手动添加该约束直接导致编译失败。同时你的泛型约束过于冗余,完全不符合当前仅处理&str的场景。
简化后的解决方案
针对你解析单/双引号字符串的需求,直接针对&str编写逻辑即可,无需复杂泛型:
use nom::{ branch::alt, bytes::complete::{escaped, tag}, character::complete::one_of, combinator::not, sequence::delimited, IResult, Parser, }; pub fn string_literal(input: &str) -> IResult<&str, &str> { // 接收分隔符,返回对应字符串解析器 fn parse_delimited_string(delim: &str) -> impl Parser<&str, &str> + '_ { // 确保分隔符是单字符(适配单/双引号场景) let delim_char = delim.chars().next().expect("分隔符必须是单字符"); delimited( tag(delim), // 匹配开头分隔符 // 解析内容:非反斜杠的任意字符,或转义后的分隔符 escaped(not(tag("\\")), '\\', one_of(delim)), tag(delim), // 匹配结尾分隔符 ) } // 同时支持单引号和双引号字符串 alt((parse_delimited_string("'"), parse_delimited_string("\"")))(input) }
关键修改点
- 移除冗余约束:删掉了包括
UnspecializedInput在内的所有不必要泛型约束,直接针对&str实现,代码大幅简化。 - 修正escaped参数:原代码中escaped的第二个参数错误地使用了分隔符字符,实际应该是转义符
'\\'(反斜杠),第三个参数才是允许转义的目标字符(即分隔符本身)。 - 精简导入:只保留实际用到的Nom组件,避免冗余。
测试示例
- 输入:
"'hello\\'world'"→ 解析结果:Ok(("", "hello'world")) - 输入:
"\"foo\\\"bar\" baz"→ 解析结果:Ok((" baz", "foo\"bar"))
内容的提问来源于stack exchange,提问作者Konrad Pagacz
相关产品推荐
相关产品推荐

