从C ++中的字符串解析键/值对

时间:2014-11-19 00:41:37

标签: c++ regex parsing c++11

我在C ++ 11工作,没有Boost。我有一个函数,它接受一个std :: string,它包含一系列键值对,用分号分隔,并返回一个从输入构造的对象。所有密钥都是必需的,但可以按任何顺序排列。

以下是输入字符串示例:

  

顶= 0;底= 6;名称=符;

这是另一个:

  

名称=酒吧;底= 20;顶= 10;

有一个相应的具体结构:

struct S 
{
    const uint8_t top;
    const uint8_t bottom;
    const string name; 
}

我通过在输入字符串上重复运行一个正则表达式来实现该函数,每个S的成员一次,并将每个捕获的组分配给S的相关成员,但这有点错误。处理这种解析的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

为了便于阅读,您可以例如使用std::regex_token_iterator和已排序的容器来区分属性值对(或者使用未排序的容器和std::sort)。

std::regex r{R"([^;]+;)"};
std::set<std::string> tokens{std::sregex_token_iterator{std::begin(s), std::end(s), r}, std::sregex_token_iterator{}};

现在,属性值字符串按字典顺序在集tokens中排序,即第一个是Bottom,然后是Name,最后是Top

最后使用简单的std::string::findstd::string::substr来提取字符串的所需部分。

Live example

答案 1 :(得分:1)

您是否关心性能或可读性?如果可读性足够好,请从this question中选择您最喜欢的split版本,然后我们离开:

std::map<std::string, std::string> tag_map;

for (const std::string& tag : split(input, ';')) {
    auto key_val = split(input, '=');
    tag_map.insert(std::make_pair(key_val[0], key_val[1]));
}


S s{std::stoi(tag_map["top"]),
    std::stoi(tag_map["bottom"]),
    tag_map["name"]};