2016-08-02 137 views
3

是否有內置的方式來迭代非空捕獲只,或者我需要使用lambda /修改我的正則表達式?有沒有辦法放棄空捕獲?

例如,給出: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和一個lambda,這就消除了很多lambda的靈活性,但是由於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

相關問題