将字符串中的数据提取到Map中的有效方法是什么?

时间:2017-05-09 23:37:28

标签: c++ regex string dictionary

这是在C ++中。我们假设我的字符串看起来像"[05]some words here [13]some more words here [17]and so on"

我想将此字符串拆分为Map<int, std::string>,其中数字作为键,文本直到下一个代码作为值。括号将被完全忽略。

到目前为止,我一直在使用标准库和SDL(我正在制作一个小游戏),但我愿意安装boost或任何其他有用的库。< / p>

我的第一个想法是要么使用一些Boosts Regex函数来进行一种正则表达式的查找和替换,或者简单地将它转换为一个char数组,通过每个字符查找括号并记录内部的数字但似乎就像它效率低下一样,特别是因为我确信在C ++中这可能是一种流行的方法。

3 个答案:

答案 0 :(得分:4)

您可以使用regex_token_iterator。这是基本的想法:

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <regex>

using namespace std;

map<int, string> extract( const std::string & s )
{
    map<int, string> m; 
    static const regex r( "\\s*\\[(\\d+)\\]" );
    sregex_token_iterator tok( s.begin(), s.end(), r, { -1, 1 } );
    tok++;  // Skip past the first end-of-sequence iterator.

    for( sregex_token_iterator end; tok != end; )
    {
        int num = stoi( *tok, nullptr, 10 );
        if( ++tok != end )
        {
            m.emplace( make_pair( num, *tok++ ) );
        }
    }
    return m;
}

int main()
{
    auto m = extract("[05]some words here [13]some more words here [17]and so on");
    for( auto & p : m ) cout << p.first << ": '" << p.second << "'" << endl;
    return 0;
}

这里,这是搜索和提取模式\s*\[(\d+)\]\s*,这意味着它将删除方括号前后的任何空格,并创建匹配组以匹配至少一个数字。

通过在迭代器上使用{-1, 1},我们要求迭代序列在匹配之前提供所有文本,然后匹配组1。

输出:

5: 'some words here'
13: 'some more words here'
17: 'and so on'

工作示例为here

答案 1 :(得分:1)

您可以使用substr()find_first_of()从字符串中提取实际数据,如下所示:

#include <string>
#include <iostream>
#include <map>

using std::string;
using std::cout;
using std::endl;
using std::map;


map<int,string> StrToMap(const string& str)
{
    map<int, string> temMap;

    for (int i(0); i < str.size(); ++i){
        if ( str[i] == '[' ){
            string tempIdx = str.substr(i+1, str.find_first_of("]",i)-i-1 );
            int a = i+str.find_first_of("]",i)-i+1;
            int b = str.find_first_of("[",a)-1;
            if ( b < 0 )
                b = str.size();
            string tempStr = str.substr(a, b-a);
            int idx = std::stoi(  tempIdx );
            temMap[idx] = tempStr; 
        }
    }

    return temMap;
}


int main(int argc, char* argv[])
{
   map<int, string> temMap = StrToMap("[05]some words here [13]some more words here [17]and so on");

  for (std::map<int, string>::const_iterator it=temMap.begin(); it!=temMap.end(); ++it)
    std::cout << it->first << " " << it->second << '\n';

    return 0;
}

结果是

5 some words here
13 some more words here
17 and so on

答案 2 :(得分:0)

您可以通过'['字符分割字符串并将部分收集到矢量中。然后,对于矢量的每个元素,将它分成两部分(在']之前和之后)。首先转换为数字并将所有内容放入地图中。这一切都将是标准的标准方法。