26

std::stringで割りたいregex

Stackoverflow でいくつかの解決策を見つけましたが、それらのほとんどは、文字列を 1 つのスペースで分割するか、boost などの外部ライブラリを使用しています。

ブーストが使えません。

文字列を正規表現で分割したい - "\\s+".

この g++ バージョンを使用してg++ (Debian 4.4.5-8) 4.4.5いますが、アップグレードできません。

4

4 に答える 4

58
#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 で動作するはずです。

于 2013-05-25T18:47:08.203 に答える
13

文字列を複数のスペースで分割するだけの場合は、正規表現を使用する必要はありません。独自の正規表現ライブラリを作成するのは、それほど単純なことにはやり過ぎです。

コメントでリンクした回答、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.length() > 0ベクトルにプッシュする前にitemelems入力に複数の区切り文字 (この場合はスペース) が含まれている場合に余分な要素を取得しないことを確認することにより、

于 2013-05-25T12:18:01.260 に答える
12

@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
于 2015-01-25T22:31:14.810 に答える