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

问题当然是我得到如下输出

豌豆和胡萝卜

甜菜
披萨

凉拌卷心菜

有没有解决的办法?

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_iflambda 来检查正则表达式匹配中的字符串是否为空。使用

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

从那些比我更聪明的人的答案来看,实际上似乎没有办法在没有 lambda 的情况下丢弃空结果。在这个问题中,有几个选择:

  1. 使用 Look Ahead,它有点贵,但只捕获没有“Spinach”的单词:
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. 使用 anistream_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

于 2016-08-02T16:51:43.710 回答