【问题标题】:Prevent escaped_list_separator from consuming quotes in quoted token防止 escaped_list_separator 使用引号中的引号
【发布时间】:2022-07-23 05:42:43
【问题描述】:

是否可以防止 boost 的 escaped_list_separator 在引用的令牌中使用引号?或者是否有任何其他现成的构造来存档此行为?
内引号无法转义,因为语法不支持,并且由第三方定义。

例子:

std::string input("ID=abcde;PARAM={this;{is};quoted}");
boost::escaped_list_separator<char> separator("", ";", "{}");
boost::tokenizer<boost::escaped_list_separator<char>> tokenizer(input, separator);

for(const auto &token : tokenizer)
{
    std::cout << token << std::endl;
}

这会产生

ID=abcde
PARAM=this;is;quoted

但我需要

ID=abcde
PARAM=this;{is};quoted

【问题讨论】:

  • 预处理输入字符串并将内部“引号”(似乎是大括号)转换为其他内容?然后将它们转换回来。
  • @PaulSanders 检测哪个字符是真正的引号字符,哪个不是并且应该替换将需要手动解析字符串,不是吗?无论如何,我可以手动标记字符串,这是我想避免的。还是我错过了什么?
  • 我认为我所说的那种预处理比自己解析整个字符串要少 - 如果你可以相信字符串格式正确,你只需要走路尽管字符串保留了未闭合大括号的数量。

标签: c++ boost boost-tokenizer


【解决方案1】:

如果要解析,请不要标记。

我会做一些假设:

  • 您想解析成键/值对映射(如 {"ID","abcde"})
  • 嵌套的 {} 大括号不能被忽略,但必须保持平衡(在这方面,它们没有被解释很奇怪,但也许你只是没有显示代码的真正用途)

示例:Spirit X3

Live On Compiler Explorer

//#define BOOST_SPIRIT_X3_DEBUG
#include <boost/fusion/adapted.hpp>  // for std::pair support
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <map>

using Map = std::map<std::string, std::string>;
using Entry = std::pair<std::string, std::string>;

namespace Grammar {
  using namespace boost::spirit::x3;

  auto entry  = rule<struct Entry_, Entry>{"entry"};
  auto quoted = rule<struct Quoted_, std::string>{"quoted"};

  auto key        = +~char_("=;");
  auto quoted_def = '{' >> raw[ *(quoted | +~char_("{}")) ] >> '}';
  auto raw        = *~char_(";");

  auto value      = quoted | raw;
  auto entry_def  = key >> '=' >> value;

  BOOST_SPIRIT_DEFINE(quoted, entry)
   
  auto full = entry % ';' >> eoi;
};

Map parse_map(std::string_view sv) {
  Map m;

  if (!parse(sv.begin(), sv.end(), Grammar::full, m))
    throw std::runtime_error("Parse error");

  return m;
}

#include <fmt/ranges.h>
int main() {
  auto m = parse_map("ID=abcde;PARAM={this;{is};quoted}");
  fmt::print("Result: {}\n", m);
}

打印

Result: {"ID": "abcde", "PARAM": "this;{is};quoted"}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 2013-11-19
    • 2018-06-06
    相关资源
    最近更新 更多