出于此问题的目的,CSV样式引用字符串是一个字符串,其中包含:
"
。"Alo""ha"
→Alo"ha
。"A""" e"
。这是A"
,其次是垃圾e"
。我尝试了几件事,但都没有完全发挥作用。
我得到的最接近的,感谢Mozilla IRC上#nom用户粉红色的一些帮助:
use std::error as stderror; /* Avoids needing nightly to compile */
named!(csv_style_string<&str, String>, map_res!(
terminated!(tag!("\""), not!(peek!(char!('"')))),
csv_string_to_string
));
fn csv_string_to_string(s: &str) -> Result<String, Box<stderror::Error>> {
Ok(s.to_string().replace("\"\"", "\""))
}
这不会正确捕获字符串的结尾。
我还尝试将re_match!
宏与r#""([^"]|"")*""#
一起使用,但总会产生Err::Incomplete(1)
。
我已经确定given CSV example for Nom 1.0对于引用的CSV字符串不起作用,因为我正在描述它,但我知道实现方式不同。
答案 0 :(得分:2)
这是一种方法:
map!()
(我用完全名词写的,但像你这样的解决方案,基于外部函数而不是nom
每个角色,也会起作用,并且可能更有效。)
这里的魔力,也可以解决你的正则表达式问题,就是使用CompleteStr。这基本上告诉nom
在输入之后没有任何内容(否则,"
假设您正在进行流式解析器,因此可能会有更多输入。)
这是必需的,因为我们需要知道如果nom
是"
的最后一个字符,该怎么办。根据其后面的字符(另一个Incomplete
,正常字符或EOF),我们必须做出不同的决定 - 因此nom
结果,意味着nom
不会有足够的投入来做出决定。告诉Incomplete
EOF接下来会解决这个犹豫不决的问题。
进一步阅读nom
作者博客上的csv_style_string
:http://unhandledexpression.com/general/2018/05/14/nom-4-0-faster-safer-simpler-parsers.html#dealing-with-incomplete-usage
您可能会注意到,此解析器实际上并不拒绝无效输入,但会解析开头并返回其余内容。如果你在另一个解析器中使用这个解析器作为子解析器,后者会将余数提供给下一个subparser,这也会崩溃(因为它会期望一个逗号),导致整个解析器失败。
如果您不想这样,可以peek!(alt!(char!(',')|char!('\n")|eof!()))
匹配Startup.cs
。