This is a variation of Parsing single-quoted string with escaped quotes with Nom 5 and Parse string with escaped single quotes. I want to parse strings like '1 \' 2 \ 3 \\ 4'
(a raw sequence of characters) as "1 \\' 2 \\ 3 \\\\ 4"
(a Rust string), so I'm not concerned with any escaping other than the possibility of having \'
inside the strings. Attempts using code from the linked questions:
use nom::{
branch::alt,
bytes::complete::{escaped, tag},
character::complete::none_of,
combinator::recognize,
multi::{many0, separated_list0},
sequence::delimited,
IResult,
};
fn parse_quoted_1(input: &str) -> IResult<&str, &str> {
delimited(
tag("'"),
alt((escaped(none_of("\\\'"), '\\', tag("'")), tag(""))),
tag("'"),
)(input)
}
fn parse_quoted_2(input: &str) -> IResult<&str, &str> {
delimited(
tag("'"),
recognize(separated_list0(tag("\\'"), many0(none_of("'")))),
tag("'"),
)(input)
}
fn main() {
println!("{:?}", parse_quoted_1(r#"'1'"#));
println!("{:?}", parse_quoted_2(r#"'1'"#));
println!("{:?}", parse_quoted_1(r#"'1 \' 2'"#));
println!("{:?}", parse_quoted_2(r#"'1 \' 2'"#));
println!("{:?}", parse_quoted_1(r#"'1 \' 2 \ 3'"#));
println!("{:?}", parse_quoted_2(r#"'1 \' 2 \ 3'"#));
println!("{:?}", parse_quoted_1(r#"'1 \' 2 \ 3 \\ 4'"#));
println!("{:?}", parse_quoted_2(r#"'1 \' 2 \ 3 \\ 4'"#));
}
/*
Ok(("", "1"))
Ok(("", "1"))
Ok(("", "1 \\' 2"))
Ok((" 2'", "1 \\"))
Err(Error(Error { input: "1 \\' 2 \\ 3'", code: Tag }))
Ok((" 2 \\ 3'", "1 \\"))
Err(Error(Error { input: "1 \\' 2 \\ 3 \\\\ 4'", code: Tag }))
Ok((" 2 \\ 3 \\\\ 4'", "1 \\"))
*/
Only first 3 cases work as intended.