如何在循环中使用boost::spirit::qi::as_string?实现可变分隔符拆分
关于boost::spirit::qi::as_string的循环使用及任意数量分隔符的字符串拆分实现
一、能否在循环中使用boost::spirit::qi::as_string?
可以在循环中使用boost::spirit::qi::as_string,只要每次循环内正确构造解析器表达式即可。比如在循环处理不同输入或动态调整规则时,直接用as_string包裹目标子解析器就能正常工作。如果循环次数极多,建议复用解析器结构以减少重复构造的性能开销。
二、支持任意数量分隔符的模板函数实现
场景1:分隔符为单个字符的字符串
如果你的分隔符是单个字符的字符串(如","、" "),可以按以下方式实现模板函数:
template <size_t N> void dac_sim::dac_ifs::dac_sim_subcmd_if::parse_cmd(std::string command, std::array<std::string, N> delimiters) { std::vector<std::string> vec; auto it = command.begin(), end = command.end(); // 组合所有分隔符为备选解析器 auto delimiter_parser = boost::spirit::qi::lit(delimiters[0]); for (size_t i = 1; i < N; ++i) { delimiter_parser |= boost::spirit::qi::lit(delimiters[i]); } // 提取所有分隔符的字符,用于构建排除规则 std::string delim_chars; for (const auto& delim : delimiters) { if (!delim.empty()) { delim_chars += delim.front(); } } // 内容解析器:匹配非分隔符的字符序列,并转换为std::string auto content_parser = boost::spirit::qi::as_string[*(boost::spirit::qi::char_ - boost::spirit::qi::char_(delim_chars))]; // 执行解析:内容解析器以分隔符为分隔,重复匹配 bool res = boost::spirit::qi::parse(it, end, content_parser % delimiter_parser, vec); std::cout << "Parsed:"; for (auto const& s : vec) std::cout << " \"" << s << "\""; std::cout << std::endl; }
场景2:分隔符为多字符的字符串
如果需要支持多字符分隔符(如"//"、"&&"),需调整内容解析器的逻辑,确保匹配到分隔符时停止:
template <size_t N> void dac_sim::dac_ifs::dac_sim_subcmd_if::parse_cmd(std::string command, std::array<std::string, N> delimiters) { std::vector<std::string> vec; auto it = command.begin(), end = command.end(); // 组合所有分隔符为备选解析器 auto delimiter_parser = boost::spirit::qi::lit(delimiters[0]); for (size_t i = 1; i < N; ++i) { delimiter_parser |= boost::spirit::qi::lit(delimiters[i]); } // 内容解析器:匹配任意字符,直到遇到分隔符(omit忽略分隔符本身的匹配结果) auto content_parser = boost::spirit::qi::as_string[*(boost::spirit::qi::char_ - boost::spirit::qi::omit(delimiter_parser))]; // 执行解析 bool res = boost::spirit::qi::parse(it, end, content_parser % delimiter_parser, vec); std::cout << "Parsed:"; for (auto const& s : vec) std::cout << " \"" << s << "\""; std::cout << std::endl; }
内容的提问来源于stack exchange,提问作者rere
相关产品推荐
相关产品推荐

