首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将istream_iterator与regex_token_iterator结合使用

将istream_iterator与regex_token_iterator结合使用
EN

Stack Overflow用户
提问于 2019-11-26 20:04:44
回答 1查看 118关注 0票数 0

是否可以将istream_iterator与类似如下的regex_token_iterator组合在一起:

代码语言:javascript
复制
std::copy(
    std::sregex_token_iterator(std::istreambuf_iterator<char>{ifs},
    std::istreambuf_iterator<char>{}, r, 1), std::sregex_token_iterator{},
    std::ostream_iterator<std::string>(std::cout)
);

给出一点背景信息。我是编程新手,我正在尝试解决一个问题,我想要删除ifstream中的所有内容,除了数字。我这样做是为了练习和学习。

输入文件如下所示:

代码语言:javascript
复制
aoisdnf 2 aopsjmdf 4 anpoidsnian 5 ainsdf 12 paalknshndf 43 aoksjhndfal 4 aslkdfoo 9 hjalkgshgdfk 4

解决方案应该如下所示:

代码语言:javascript
复制
2 4 5 12 43 4 9 4

我的第一个方法是:

代码语言:javascript
复制
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctype.h>

int main()
{
   std::ifstream ifs ("C:/Users/../whitespace_seperated_integers.txt", std::ifstream::in);
   std::string tmp;
   std::vector<int> vector;

   for (auto it = std::istreambuf_iterator<char>{ifs}; it != std::istreambuf_iterator<char>{}; ++it) {
      if (*it >= '0' && *it <= '9') tmp.append(1, *it);
      else if (!tmp.empty()){
         vector.push_back(std::stoi(tmp));
         tmp.clear();
      }
   }
   if (!tmp.empty()) vector.push_back(std::stoi(tmp));

   for(const auto i : vector){
      std::cout << i << " ";
   }

它工作得很好,但后来我有了用regex解决这个问题的想法,这导致了这个解决方案:

代码语言:javascript
复制
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctype.h>
#include <regex>

int main()
{
   std::ifstream ifs ("C:/Users/../whitespace_seperated_integers.txt", std::ifstream::in);
   std::string puf;
   std::vector<std::string> vector;
   std::string line;
   char wts = ' ';
   while(getline(ifs ,line, wts)){
      puf += line;
   }
   std::regex r(R"([^\d]*(\d+))");
   std::copy(std::sregex_token_iterator(puf.begin(), puf.end(), r, 1), std::sregex_token_iterator(), std::back_inserter(vector));

   std::vector<int> vec;
   std::smatch sm;
   while(std::regex_search(puf, sm, r))
   {
      vec.push_back(std::stoi(sm[1]));
      /* std::cout << sm[1] << '\n';*/
      puf = sm.suffix();
   }
   for(const auto i : vec){
      std::cout << i << " ";
   }
}

但我对这段代码并不是很满意,所以我想找出如何改进它。我试着把istream_iterator和regex_token_iterator结合起来,但是我不知道它是如何工作的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-26 23:52:07

如果您真的想使用std::sregex_token_iterator,那么您可能需要选择不同的方法。

对于给定的字符串,您需要提取数字。我们可以改变观察角度并使用不同的算法。如果我们确实看到了除数字以外的所有内容作为分隔符,我们可以使用带有索引参数-1的std::sregex_token_iterator来拆分字符串。

所以,秘诀就是新的分隔符。那么结果就是一行代码

代码语言:javascript
复制
#include <iostream>
#include <regex>
#include <vector>
#include <iterator>
#include <string>

int main()
{
    // The test string
    std::string test{"aoisdnf 2 aopsjmdf 4 anpoidsnian 5 ainsdf 12 paalknshndf 43 aoksjhndfal 4 aslkdfoo 9 hjalkgshgdfk 4"};

    // regex for anything but a digit
    const std::regex re {R"([\D]+)"};

    // Get all digits from the test string
    std::vector<std::string> token(std::sregex_token_iterator(test.begin(),test.end(),re, -1), {});

    // Output result
    std::copy(token.begin(), token.end(), std::ostream_iterator<std::string>(std::cout," "));

    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59050581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档