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"));

もちろん問題は、次のような出力が得られることです。

ピーズ&キャロット

ビーツ
ピザ

コールスロー

これを回避する方法はありますか?

4

3 に答える 3

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(); } 
);
于 2016-08-02T15:31:48.210 に答える
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

実際の例

空でない文字列のみを出力するためです。

于 2016-08-02T15:31:57.740 に答える
0

私よりも賢い人の答えからすると、ラムダなしで空の結果を破棄する方法は実際にはないようです。ただし、この質問にはいくつかの選択肢があります。

  1. もう少しコストがかかりますが、"Spinach" を含まない単語のみをキャプチャする Look Ahead を使用します。
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と、ラムダの柔軟性が大幅に失われますが、input空白で区切られているため、これがおそらく最良のオプションです。
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

于 2016-08-02T16:51:43.710 に答える