问题描述
我正在尝试使用boost spirit解析包含转义序列的带引号的字符串.我正在寻找一种将转义序列 \"
替换为相应字符(在这种情况下为"
)的方法.到目前为止,我已经提出了这个建议.
I'm trying to parse a quoted string containing escape sequences using boost spirit. I'm looking for a way to replace escape sequences \"
with the corresponding character ("
in this case). So far I've come up with this.
c_string%= lit('')>> *(lit(" \\\")[push_back(_val,'')]] |(char_-'"'))>>lit('')
替换完成
lit("\\\")[push_back(_val,'"')]
但是,在我看来,这很笨拙且难以理解.有没有更好的方法可以做到这一点?
however this seems to me quite clumsy and unreadable. Is there a better way to accomplish this?
推荐答案
迭代:您可以将"\\\""
替换为'\\'>> lit('')
,重新格式化一下:
Iterating: you can replace "\\\""
with '\\' >> lit('"')
, reformatting a bit:
c_string
%= lit('"')
>> *(
'\\' >> lit('"')[push_back(_val, '"')]
| (char_ - '"')
)
>> lit('"')
;
现在,您可以取消某些 lit()
调用,因为在Qi域中调用原型表达式时它们是隐式的:
Now, you can do away with some of the lit()
calls because they're implicit when invoking proto expressions in the Qi domain:
c_string
%= '"'
>> *(
'\\' >> lit('"')[push_back(_val, '"')]
| (char_ - '"')
)
>> '"'
;
接下来, lit(ch)[push_back(_val,ch)]
只是一种笨拙的方式来表达 char_(ch)
:
Next up, lit(ch)[push_back(_val, ch)]
is just a clumsy way to say char_(ch)
:
c_string = '"'
>> *( '\\' >> char_('"') | (char_ - '"') )
>> '"';
最后,您可以说出〜char_(xyz)
:
c_string = '"' >> *('\\' >> char_('"') | ~char_('"')) >> '"';
现在,您实际上并没有在这里解析C样式的字符串.您不处理转义符,为什么不简化:
Now, you're not actually parsing C-style strings here. You're not handling escapes, so why not simplify:
c_string = '"' >> *('\\' >> char_|~char_('"')) >> '"';
如果您想更加精确,请考虑处理转义符,例如在Boost.Spirit中处理utf-8utf-32解析器
If you want to be more precise, consider handling escapes like e.g. Handling utf-8 in Boost.Spirit with utf-32 parser
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
const qi::rule<std::string::const_iterator, std::string()> c_string
= '"' >> *('\\' >> qi::char_|~qi::char_('"')) >> '"';
for (std::string const input: {
R"("")" , // ""
R"("\"")" , // "\\\""
R"("Hello \"world\"")", // "Hello \\\"world\\\""
})
{
std::string output;
if (parse(input.begin(), input.end(), c_string, output)) {
std::cout << input << " -> " << output << "\n";
} else {
std::cout << "Failed: " << input << "\n";
}
}
}
打印
"" ->
"\"" -> "
"Hello \"world\"" -> Hello "world"
这篇关于用激发精神中的其他弦代替点燃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!