指定不使用范围

时间:2015-05-12 11:18:21

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

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

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

字符串
*(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);
}

看起来很优雅。 在使用静态常量规则的情况下,我想我可以使用'\'转义字符,方括号被认为是需要转义的那些“特殊”字符之一。为什么?的意义是什么 []?还有其他角色可以逃脱吗?

2 个答案:

答案 0 :(得分:1)

简单。

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

接下来,

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

  • 根本不使用字符集。

    • 为什么不使用char_ [ _pass = my_match_predicate(_1) ]
    • 为什么不改变字面字符呢? lit('a') | 'b' | '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    • 为什么不使用qi::symbols<char, char>(甚至qi::symbols<char, qi::unused_type> sym_;raw [ sym_ ]或类似的

        

      更新 qi::symbols<>方法速度惊人:Live On Coliru。我有一个最近的优化工作,它很失望:看到这个答案(在&#34;精神(特里)&#34;) - Binary String to Hex c++

一般来说,我不知道你想要实现的目标,但是精神 并不适合动态生成规则。请参阅本网站上现有的个答案。

答案 1 :(得分:0)

您是否尝试使用\ - bk::char_("a-zA-Z0-9\\-_.~")