2017-05-09 36 views
2

这是用C++编写的。比方说,我有一个看起来像这样的字符串"[05]some words here [13]some more words here [17]and so on"什么是从字符串中提取数据到Map中的有效方法?

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

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

我首先想到的是,无论是使用一些增强的正则表达式的功能做了一种正则表达式的查找和替换,或者简单地将其转换为字符数组经历的每一个字符寻找托架和记录里面的电话号码,但是看起来效率不高,特别是因为我确信在C++中可能使用这种方法。

+0

*字符数组通过每一个人物去...这将是低效*。为什么效率低下?! – CroCo

回答

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 
+0

谢谢你向我展示我的方式错误。根据我的测试,你的方法是最快的,这与我期待的相反! – user3445644

0

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

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

+0

谢谢,我能够学习如何使用regex_token_iterator感谢你的例子! – user3445644

相关问题