boost::spirit::qi 保留白色 space
boost::spirit::qi preserving white space
我正在使用此代码将 "k1=v1;k2=v2;k3=v3;kn=vn" 字符串解析为映射。
qi::phrase_parse(
begin,end,
*(*~qi::char_('=') >> '=' >> *~qi::char_(';') >> -qi::lit(';')),
qi::ascii::space, dict);
以上代码将删除 space 个字符,例如"some_key=1 2 3" 变为 some_key -> 123
我不知道如何删除或用第四个参数替换什么:qi::ascii::space
基本上,我想在按“=”拆分后保留原始字符串(键和值)。
我没有多少experience/knowledge精神。它确实需要投入时间来学习。
如果你不想要船长,只需使用 qi::parse
而不是 qi::phrase_parse
:
qi::parse(
begin,end,
*(*~qi::char_(";=") >> '=' >> *~qi::char_(';') >> -qi::lit(';')),
dict);
但是,您可能确实希望有选择地跳过空格。最简单的方法通常是有一个通用船长,然后标记词位区域(不允许船长的地方):
qi::phrase_parse(
begin, end,
*(qi::lexeme[+(qi::graph - '=')]
>> '='
>> qi::lexeme[*~qi::char_(';')] >> (qi::eoi|';')),
qi::ascii::space, dict);
linked answer 确实提供了更多关于如何在 Qi 中与船长一起工作的 techniques/backgrounds
演示时间
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>
#include <iomanip>
namespace qi = boost::spirit::qi;
int main() {
for (std::string const& input : {
R"()",
R"(foo=bar)",
R"(foo=bar;)",
R"( foo = bar ; )",
R"( foo = bar ;
foo
= qux; baz =
quux
corge grault
thud
; x=)",
// failing:
R"(;foo = bar;)",
})
{
std::cout << "-------------------------\n";
auto f=begin(input), l=end(input);
std::multimap<std::string, std::string> dict;
bool ok = qi::phrase_parse(f, l,
(qi::lexeme[+(qi::graph - '=' - ';')]
>> '='
>> qi::lexeme[*~qi::char_(';')]
) % ';',
qi::space,
dict);
if (ok) {
std::cout << "Parsed " << dict.size() << " elements:\n";
for (auto& [k,v]: dict) {
std::cout << " - " << std::quoted(k) << " -> " << std::quoted(v) << "\n";
}
} else {
std::cout << "Parse failed\n";
}
if (f!=l) {
std::cout << "Remaining input: " << std::quoted(std::string(f,l)) << "\n";
}
}
}
版画
-------------------------
Parse failed
-------------------------
Parsed 1 elements:
- "foo" -> "bar"
-------------------------
Parsed 1 elements:
- "foo" -> "bar"
Remaining input: ";"
-------------------------
Parsed 1 elements:
- "foo" -> "bar "
Remaining input: "; "
-------------------------
Parsed 4 elements:
- "baz" -> "quux
corge grault
thud
"
- "foo" -> "bar "
- "foo" -> "qux"
- "x" -> ""
-------------------------
Parse failed
Remaining input: ";foo = bar;"
我正在使用此代码将 "k1=v1;k2=v2;k3=v3;kn=vn" 字符串解析为映射。
qi::phrase_parse(
begin,end,
*(*~qi::char_('=') >> '=' >> *~qi::char_(';') >> -qi::lit(';')),
qi::ascii::space, dict);
以上代码将删除 space 个字符,例如"some_key=1 2 3" 变为 some_key -> 123
我不知道如何删除或用第四个参数替换什么:qi::ascii::space
基本上,我想在按“=”拆分后保留原始字符串(键和值)。
我没有多少experience/knowledge精神。它确实需要投入时间来学习。
如果你不想要船长,只需使用 qi::parse
而不是 qi::phrase_parse
:
qi::parse(
begin,end,
*(*~qi::char_(";=") >> '=' >> *~qi::char_(';') >> -qi::lit(';')),
dict);
但是,您可能确实希望有选择地跳过空格。最简单的方法通常是有一个通用船长,然后标记词位区域(不允许船长的地方):
qi::phrase_parse(
begin, end,
*(qi::lexeme[+(qi::graph - '=')]
>> '='
>> qi::lexeme[*~qi::char_(';')] >> (qi::eoi|';')),
qi::ascii::space, dict);
linked answer 确实提供了更多关于如何在 Qi 中与船长一起工作的 techniques/backgrounds
演示时间
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>
#include <iomanip>
namespace qi = boost::spirit::qi;
int main() {
for (std::string const& input : {
R"()",
R"(foo=bar)",
R"(foo=bar;)",
R"( foo = bar ; )",
R"( foo = bar ;
foo
= qux; baz =
quux
corge grault
thud
; x=)",
// failing:
R"(;foo = bar;)",
})
{
std::cout << "-------------------------\n";
auto f=begin(input), l=end(input);
std::multimap<std::string, std::string> dict;
bool ok = qi::phrase_parse(f, l,
(qi::lexeme[+(qi::graph - '=' - ';')]
>> '='
>> qi::lexeme[*~qi::char_(';')]
) % ';',
qi::space,
dict);
if (ok) {
std::cout << "Parsed " << dict.size() << " elements:\n";
for (auto& [k,v]: dict) {
std::cout << " - " << std::quoted(k) << " -> " << std::quoted(v) << "\n";
}
} else {
std::cout << "Parse failed\n";
}
if (f!=l) {
std::cout << "Remaining input: " << std::quoted(std::string(f,l)) << "\n";
}
}
}
版画
-------------------------
Parse failed
-------------------------
Parsed 1 elements:
- "foo" -> "bar"
-------------------------
Parsed 1 elements:
- "foo" -> "bar"
Remaining input: ";"
-------------------------
Parsed 1 elements:
- "foo" -> "bar "
Remaining input: "; "
-------------------------
Parsed 4 elements:
- "baz" -> "quux
corge grault
thud
"
- "foo" -> "bar "
- "foo" -> "qux"
- "x" -> ""
-------------------------
Parse failed
Remaining input: ";foo = bar;"