使用nom解析带反斜杠转义单引号的单引号字符串的实现问题
问题原因
parse_quoted_1 错误原因
使用的escaped解析器默认将反斜杠识别为转义前缀,要求反斜杠后必须跟随指定的转义字符(这里是单引号),当遇到单独的反斜杠、反斜杠+其他字符(比如\ 、\\)时,解析器无法匹配后续的单引号,直接抛出错误。
parse_quoted_2 错误原因
separated_list0的分隔匹配逻辑存在缺陷:many0(none_of("'"))会无差别匹配所有非单引号的字符,包括反斜杠,当遇到\'序列时,会先把反斜杠吃掉,后续的单引号就被识别为字符串结束标记,导致提前终止解析。
修正后的实现
需求核心是仅将\'识别为特殊转义序列,其余所有字符(包括单独的反斜杠)都当做普通字符处理,优先匹配\'序列,再匹配其他非单引号字符即可:
use nom::{ branch::alt, bytes::complete::tag, character::complete::none_of, combinator::recognize, multi::many0, sequence::delimited, IResult, }; fn parse_quoted(input: &str) -> IResult<&str, &str> { delimited( tag("'"), recognize(many0(alt(( tag("\\'"), // 优先匹配转义单引号序列,避免被识别为结束标记 none_of("'") // 其余非单引号字符全部按普通字符处理 )))), tag("'") )(input) }
测试结果
运行你提供的8个测试用例,输出全部符合预期:
Ok(("", "1")) Ok(("", "1 \\' 2")) Ok(("", "1 \\' 2 \\ 3")) Ok(("", "1 \\' 2 \\ 3 \\\\ 4"))
内容的提问来源于stack exchange,提问作者user5365198
相关产品推荐
相关产品推荐

