【问题标题】:Specify a charset without intepreting ranges指定不解释范围的字符集
【发布时间】:2015-07-23 05:36:37
【问题描述】:

当我必须在规则中定义减号并且它只是一个减号而不是两个端点之间的字符范围时,我对解析字符串感到非常困惑。

例如,当您编写规则来对字符串进行百分比编码时,您通常会编写

*(bk::char_("a-zA-Z0-9-_.~") | '%' << bk::right_align(2, 0)[bk::upper[bk::hex]]);

这通常表示“字母、大写字母、数字、减号、下划线、点和波浪号”,但第三个减号会创建一个介于 9 和下划线之类的范围,所以你必须把减号放在末尾bk::char_("a-zA-Z0-9_.~-").

它解决了当前的问题,但是当输入是动态的,比如用户输入,而减号只是表示减号时,该怎么办?

如何防止 Spirit 为任何可能的字符赋予特殊含义?

EDIT001: 我求助于@sehe answer

的更具体的例子
void spirit_direct(std::vector<std::string>& result, const std::string& input, char const* delimiter)
{
    result.clear();
    using namespace bsq;
    if(!parse(input.begin(), input.end(), raw[*(char_ - char_(delimiter))] % char_(delimiter), result))
        result.push_back(input);
}

如果您想确保将减号视为减号而不是范围,则可以按以下方式更改代码(根据下面的@sehe 建议)。

void spirit_direct(std::vector<std::string>& result, const std::string&
    input, char const* delimiter)
{
    result.clear();
    bsq::symbols<char, bsq::unused_type> sym_;
    std::string separators = delimiter;
    for(auto ch : separators)
    {
        sym_.add(std::string(1, ch));
    }
    using namespace bsq;
    if(!parse(input.begin(), input.end(), raw[*(char_ - sym_)] % sym_, result))
        result.push_back(input);
}

看起来很优雅。 如果使用静态常量规则,我想我可以用“\”转义字符,方括号是指需要转义的“特殊”字符之一。为什么?是什么意思 []?是否有任何额外的字符可以转义?

【问题讨论】:

    标签: c++ boost boost-spirit-qi


    【解决方案1】:

    简单。

    您设计并指定用户可以提供的受支持模式及其含义。

    接下来,

    • 您编写将其转换为字符集的代码(例如,扩展所有范围(如果用户输入支持)并将- 排序为定义的第一个字符)。

    • 根本不使用字符集。

      • 为什么不使用char_ [ _pass = my_match_predicate(_1) ]
      • 为什么不直接替换文字字符呢? lit('a') | 'b' | '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
      • 为什么不使用qi::symbols&lt;char, char&gt;(甚至qi::symbols&lt;char, qi::unused_type&gt; sym_;raw [ sym_ ] 或类似的)

        更新qi::symbols&lt;&gt; 方法速度惊人:Live On Coliru。我最近的一项优化工作令人失望:请参阅此答案(在“Spirit (Trie)”下)– Binary String to Hex c++

    一般来说,我不知道您想要实现什么,但 Spirit 非常适合动态生成规则。在这个网站上查看我现有的一些 答案。

    【讨论】:

    • 嗬嗬,你有很多:) 让我们看看你的答案stackoverflow.com/questions/30046512/… 考虑“分隔符”是“,|-~”然后它将捕获 4 个分隔符(',',' |','}','~') 当平均 Joe 也表示 4 个分隔符但 ',','|','-','~' 时。我不能指定输入模式太“远”,它应该是向后兼容的(减号只是意味着减号)。至于下一点 - 1)不优雅。 2a) 看起来很麻烦,但也许我没明白。 2b)好多了,但又不是优雅的顶峰。 2c) 看起来就像医生要求的一样
    • @kreuzerkrieg “它应该是向后兼容的” - 看,这是你的规范!关于链接的答案...what's wrong with a simple ordering?
    • 就是这样,这不是我的规范......长篇大论......订购的东西 - 好的东西,它又好又丑:) 恕我直言,符号的东西更具可读性和更容易理解
    • @kreuzerkrieg OT 但那是因为您正在向帖子的作者(Q 或 A)致辞,而评论线程中没有其他人参与。有点违反Principle Of Least Surprise 但哦,好吧:)
    • 实际上...打击那个。 qi::symbols&lt;&gt; 方法速度惊人:Live On Coliru。我最近的优化工作令人失望:see this answer (under "Spirit (Trie)"))
    【解决方案2】:

    你试过用\-bk::char_("a-zA-Z0-9\\-_.~")吗?

    【讨论】:

    • 不,因为我正在寻找类似禁用特殊字符含义的指令
    • @kreuzerkrieg 它不存在。
    猜你喜欢
    • 2015-02-26
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 2013-06-06
    • 2019-09-11
    • 2018-06-09
    相关资源
    最近更新 更多