2016-08-02 6 views
3

空でないキャプチャだけを繰り返し処理する方法がありますか、またはラムダを使用して正規表現を変更する必要がありますか?空のキャプチャを破棄する方法はありますか?

たとえば:const auto input = "Peas&Carrots Spinach-Casserole Beets Pizza Spinach-Salad Coleslaw"sは「ほうれん草」を含むの食品を見つけたいと思います。だから私はこれを行うことができます。

const regex re{ "\\s*(?:\\S*Spinach\\S*|(\\S*))" }; 

copy(sregex_token_iterator(cbegin(input), cend(input), re, 1), sregex_token_iterator(), ostream_iterator<string>(cout, "\n")); 

もちろんの問題は、I get an outputよう:

ピーズ&人参

ビーツ
ピザ

コールスロー

これには方法がありますか?

答えて

1

あなたは正規表現のマッチから文字列が空であるかないことを確認するためにstd::copy_ifとラムダを使用することができます。それが唯一の非空の文字列を出力しますと

copy_if(sregex_token_iterator(cbegin(input), cend(input), re, 1), 
     sregex_token_iterator(), ostream_iterator<string>(cout, "\n"), 
     [](const std::string& match){ return !match.empty(); }); 

を使用して、我々は

Peas&Carrots 
Beets 
Pizza 
Coleslaw 

Live Example

を取得します。

1

明らかな方法は、std::copy_if(またはstd::remove_copy_if)を使用し、文字列が空でない場合にのみコピーすることです。

remove_copy_if(
    sregex_token_iterator(cbegin(input), cend(input), re, 1), 
    sregex_token_iterator(), 
    ostream_iterator<string>(cout, "\n"), 
    [](string const &s) { return s.empty(); } 
); 
0

私よりも賢い人の答えから、ラムダなしで空の結果を破棄する方法は実際にはないようです。

  1. は少し高価である先読みを使用しますが、唯一「ほうれん草」せずに言葉をキャプチャ:この質問ではカップルの選択肢は、しかしある
const regex re{ "(?:\\s+|^)(?!Spinach)(\\S+)" }; 

copy(sregex_token_iterator(cbegin(input), cend(input), re, 1), sregex_token_iterator(), ostream_iterator<string>(cout, "\n")); 

Live Example

  1. istream_iteratorとラムダを使用すると、ラムダの柔軟性が大幅に失われますが、以降
istringstream{ input }; 

copy_if(istream_iterator<string>(cbegin(input), cend(input)), istream_iterator<string>(), ostream_iterator<string>(cout, "\n"), [](const auto& i) { return i.find("Spinach") == string::npos; }); 

Live Example

:が、これはおそらく最良の選択肢である区切りの空白です
関連する問題