You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Boost Spirit Qi解析带大小写不敏感公制前缀的数值并返回转换后的值?

实现带公制前缀的数值解析(Boost Spirit Qi)

要实现将带公制前缀的字符串转换为对应数值,核心是通过语义动作将匹配到的后缀映射为乘数,再与前面的数值相乘得到最终结果。以下是修改后的完整代码:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;

using iter = std::string::const_iterator;

class MyGrammar : public qi::grammar<iter, double()>
{
public:
    MyGrammar() : MyGrammar::base_type(start)
    {
        // 定义后缀与乘数的映射,支持大小写不敏感
        suffix = qi::no_case[
            qi::char_('k')[qi::_val = 1000.0]
        ];

        // 主规则:数值 * 乘数(无后缀时乘数为1.0)
        start = (qi::double_ >> suffix)[qi::_val = qi::_1 * qi::_2] 
              | qi::double_[qi::_val = qi::_1];
    }

    qi::rule<iter, double()> suffix; 
    qi::rule<iter, double()> start;
};

// 测试示例
#include <iostream>
#include <string>

int main()
{
    MyGrammar grammar;
    std::string input1 = "10k";
    std::string input2 = "15.5K";
    std::string input3 = "200";

    double result;
    iter begin, end;

    begin = input1.begin(); end = input1.end();
    if (qi::parse(begin, end, grammar, result)) {
        std::cout << input1 << " → " << result << std::endl; // 输出10000
    }

    begin = input2.begin(); end = input2.end();
    if (qi::parse(begin, end, grammar, result)) {
        std::cout << input2 << " → " << result << std::endl; // 输出15500
    }

    begin = input3.begin(); end = input3.end();
    if (qi::parse(begin, end, grammar, result)) {
        std::cout << input3 << " → " << result << std::endl; // 输出200
    }

    return 0;
}

关键修改说明:

  • 调整模板参数:将qi::grammar<iter>改为qi::grammar<iter, double()>,表示整个语法解析后返回double类型;规则suffix和start也对应改为qi::rule<iter, double()>,用于返回乘数和最终结果。
  • 语义动作映射乘数:通过qi::_val设置规则的返回值,比如匹配到k或K时,suffix规则返回1000.0。使用qi::no_case简化大小写不敏感匹配,无需分别写'k'和'K'。
  • 计算最终结果:主规则start中,用qi::_1获取前面的数值,qi::_2获取后缀的乘数,两者相乘后赋值给qi::_val作为最终结果;无后缀的分支直接返回原始数值。
  • 依赖Phoenix库:语义动作需要Boost Phoenix支持,因此要包含<boost/spirit/include/phoenix.hpp>,qi::_1、qi::_2、qi::_val都是Phoenix的占位符。

如果需要扩展更多公制前缀(如m对应0.001,M对应1e6等),只需在suffix规则中添加更多分支即可,例如:

suffix = qi::no_case[
    qi::char_('k')[qi::_val = 1000.0]
  | qi::char_('m')[qi::_val = 0.001]
  | qi::char_('M')[qi::_val = 1e6]
];

内容的提问来源于stack exchange,提问作者user3814483

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 19:32:35