如何在 rust 中使用 nom 解析对称带引号的字符串?

  • 本文关键字:对称 字符串 rust nom rust nom
  • 更新时间 :
  • 英文 :


我应该如何使用nom解析类似于rust的原始字符串的带引号的字符串? 我想解析以下内容:

"A standard string"
#"A string containing ["] a quote"#
##"A string containing ["#] a quote and hash "##

我将如何做到这一点,要求在开头和结尾使用相同数量的"#"符号,同时允许 #'ed 字符串包含未转义的引号和哈希?

这将是我的方法(使用nom-5.1.1(:

extern crate nom;
use nom::{
IResult,
multi::{count, fold_many0, many_till},
bytes::complete::{tag, take},
sequence::pair
};
fn quoted_str(input: &str) -> IResult<&str, &str> {
// Count number of leading #
let (remaining, hash_count) = fold_many0(tag("#"), 0, |acc, _| acc + 1)(input)?;
// Match "
let (remaining, _) = tag(""")(remaining)?;
// Take until closing " plus # (repeated hash_count times)
let closing = pair(tag("""), count(tag("#"), hash_count));
let (remaining, (inner, _)) = many_till(take(1u32), closing)(remaining)?;
// Extract inner range
let offset = hash_count + 1;
let length = inner.len();
Ok((remaining, &input[offset .. offset + length]))
}
#[test]
fn run_test() {
assert_eq!(quoted_str(""ABC""), Ok(("", "ABC")));
assert_eq!(quoted_str("#"ABC"#"), Ok(("", "ABC")));
assert_eq!(quoted_str("##"ABC"##"), Ok(("", "ABC")));
assert_eq!(quoted_str("###"ABC"###"), Ok(("", "ABC")));
assert_eq!(quoted_str("#"ABC"XYZ"#"), Ok(("", "ABC"XYZ")));
assert_eq!(quoted_str("#"ABC"#XYZ"#"), Ok(("XYZ"#", "ABC")));
assert_eq!(quoted_str("#"ABC"##XYZ"#"), Ok(("#XYZ"#", "ABC")));
assert_eq!(quoted_str("##"ABC"XYZ"##"), Ok(("", "ABC"XYZ")));
assert_eq!(quoted_str("##"ABC"#XYZ"##"), Ok(("", "ABC"#XYZ")));
assert_eq!(quoted_str("##"ABC"##XYZ"##"), Ok(("XYZ"##", "ABC")));
assert_eq!(quoted_str("##"ABC"###XYZ"##"), Ok(("#XYZ"##", "ABC")));
assert_eq!(quoted_str(""ABC"XYZ"), Ok(("XYZ", "ABC")));
assert_eq!(quoted_str("#"ABC"#XYZ"), Ok(("XYZ", "ABC")));
assert_eq!(quoted_str("##"ABC"##XYZ"), Ok(("XYZ", "ABC")));
}

如果性能对您很重要,则可以通过编写基于fold_many0many_fill代码的fold_many_till函数来避免many_till中的隐式向量分配。似乎nom目前没有提供这样的功能。

相关内容

  • 没有找到相关文章

最新更新