【问题标题】:C++ - Split string by regexC++ - 通过正则表达式分割字符串
【发布时间】:2013-05-20 21:17:40
【问题描述】:

我想将std::string 拆分为regex

我在 Stackoverflow 上找到了一些解决方案,但大多数都是用单个空格分割字符串或使用诸如 boost 之类的外部库。

我不能使用 boost。

我想用正则表达式分割字符串 - "\\s+"

我正在使用这个 g++ 版本g++ (Debian 4.4.5-8) 4.4.5,我无法升级。

【问题讨论】:

  • 知道我正在使用这个函数来拆分字符串:stackoverflow.com/a/236803/418518 它只适用于 single char。正则表达式格式是正确的,我已经在一个java项目中使用过他。工作出色。
  • 问题是我不太了解 C++... 我只想知道如何使用旧的 c++ 标准(可能是C++03)拆分 std::string。如果您有一些链接/代码,请粘贴它。 :) 谢谢!
  • 你能显示示例输入和所需的输出吗?
  • 使用boost 可能是一种选择。
  • @melwil:所需输入/输出:gist.github.com/maciejkowalski/af7e0ce2b92d967e050c

标签: c++ regex string split


【解决方案1】:
#include <regex>

std::regex rgx("\\s+");
std::sregex_token_iterator iter(string_to_split.begin(),
    string_to_split.end(),
    rgx,
    -1);
std::sregex_token_iterator end;
for ( ; iter != end; ++iter)
    std::cout << *iter << '\n';

-1 是这里的关键:构造迭代器时,迭代器指向匹配之前的文本,每次递增后,迭代器指向上一个匹配之后的文本。

如果您没有 C++11,同样的事情应该适用于 TR1 或(可能稍作修改)适用于 Boost。

【讨论】:

  • @Narek - 要么,要么添加显式模板参数:regex_token_iterator&lt;std::string::iterator&gt;sregex_token_iterator 更容易。固定的。谢谢。
  • cplusplus.com reference doc 上的最后一个示例与此答案类似
【解决方案2】:

如果你只想用多个空格分割一个字符串,你不需要使用正则表达式。编写自己的正则表达式库对于这么简单的事情来说太过分了。

您在 cmets 中链接到的答案 Split a string in C++? 可以轻松更改,以便在有多个空格时不包含任何空元素。

std::vector<std::string> &split(const std::string &s, char delim,std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        if (item.length() > 0) {
            elems.push_back(item);  
        }
    }
    return elems;
}


std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}

通过在将item 推送到elems 向量之前检查item.length() &gt; 0,如果您的输入包含多个分隔符(在您的情况下为空格),您将不再获得额外的元素

【讨论】:

  • 好吧,我们在同一时间找到了同样的方法。 :) 但实际上你在 SO 上粘贴答案的速度更快(约 10 分钟)。 +1 并接受。
  • 您也应该同意这样一个事实,即使用 C++ 拆分字符串看起来更大,在 C# 中您只需执行 str.split(...) ;)
【解决方案3】:

为了扩展@Pete Becker 的答案,我提供了一个 resplit 函数的示例,该函数可用于使用正则表达式拆分文本:

  #include <regex>

  std::vector<std::string>
  resplit(const std::string & s, std::string rgx_str = "\\s+") {


      std::vector<std::string> elems;

      std::regex rgx (rgx_str);

      std::sregex_token_iterator iter(s.begin(), s.end(), rgx, -1);
      std::sregex_token_iterator end;

      while (iter != end)  {
          //std::cout << "S43:" << *iter << std::endl;
          elems.push_back(*iter);
          ++iter;
      }

      return elems;

  }

它的工作原理如下:

   string s1 = "first   second third    ";
   vector<string> v22 = my::resplit(s1);

   for (const auto & e: v22) {
       cout <<"Token:" << e << endl;
   }


   //Token:first
   //Token:second
   //Token:third


   string s222 = "first|second:third,forth";
   vector<string> v222 = my::resplit(s222, "[|:,]");

   for (const auto & e: v222) {
       cout <<"Token:" << e << endl;
   }


   //Token:first
   //Token:second
   //Token:third
   //Token:forth

【讨论】:

    【解决方案4】:
    string s = "foo bar  baz";
    regex e("\\s+");
    regex_token_iterator<string::iterator> i(s.begin(), s.end(), e, -1);
    regex_token_iterator<string::iterator> end;
    while (i != end)
       cout << " [" << *i++ << "]";
    

    打印[foo] [bar] [baz]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      相关资源
      最近更新 更多