parsing - 解析带有转义单引号的字符串

标签 parsing rust nom

我想解析一个字符串,其中包含单引号之间的 ASCII 字符,并且可以包含连续两个 ' 的转义单引号。

'string value contained between single quotes -> '' and so on...'

结果应该是:

string value contained between single quotes -> ' and so on...

use nom::{
    bytes::complete::{tag, take_while},
    error::{ErrorKind, ParseError},
    sequence::delimited,
    IResult,
};

fn main() {
    let res = string_value::<(&str, ErrorKind)>("'abc''def'");

    assert_eq!(res, Ok(("", "abc\'def")));
}

pub fn is_ascii_char(chr: char) -> bool {
    chr.is_ascii()
}

fn string_value<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
    delimited(tag("'"), take_while(is_ascii_char), tag("'"))(i)
}

如何检测转义引号而不是字符串结尾?

最佳答案

这很棘手,但以下是可行的:

//# nom = "5.0.1"
use nom::{
    bytes::complete::{escaped_transform, tag},
    character::complete::none_of,
    combinator::{recognize, map_parser},
    multi::{many0, separated_list},
    sequence::delimited,
    IResult,
};

fn main() {
    let (_, res) = parse_quoted("'abc''def'").unwrap();
    assert_eq!(res, "abc'def");
    let (_, res) = parse_quoted("'xy@$%!z'").unwrap();
    assert_eq!(res, "xy@$%!z");
    let (_, res) = parse_quoted("'single quotes -> '' and so on...'").unwrap();
    assert_eq!(res, "single quotes -> ' and so on...");
}

fn parse_quoted(input: &str) -> IResult<&str, String> {
    let seq = recognize(separated_list(tag("''"), many0(none_of("'"))));
    let unquote = escaped_transform(none_of("'"), '\'', tag("'"));
    let res = delimited(tag("'"), map_parser(seq, unquote), tag("'"))(input)?;

    Ok(res)
}

一些解释:

  1. 解析器 seq 可以识别在双引号和其他任何内容之间交替出现的任何序列;
  2. unquote 将任何双引号转换为单引号;
  3. map_parser 然后将两者组合在一起以产生所需的结果。

请注意,由于使用了 escaped_transform 组合器,解析结果是 String 而不是 &str。即,有额外的分配。

关于parsing - 解析带有转义单引号的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58511515/

相关文章:

rust - 为什么删除返回给我一个错误 : expected type `()` but found type

reflection - 是否可以使用其中一种方法获取结构的名称?

Python 使用 ctypes 调用 Rust FFI 在退出时崩溃并返回 "pointer being freed was not allocated"

rust - 为什么在名为!的宏中将 nom 的 CompleteStr 转换为字符串?返回结果?

sql - 在 Oracle SQL 中解析具有未知 namespace 的 XML

PHP获取html源,然后解析某些DIV标签内的值

使用 nom 解析自定义标识符

generics - 如何包装nom tag_no_case解析器?

java - 如何在java中解析build.gradle文件?

parsing - 在 Haskell 的 uu-parsinglib 中自定义错误处理