有没有一种方法来抛弃空的捕获?

3

有没有一种内置的方法只迭代非空捕获,或者我需要使用lambda/修改我的正则表达式?

例如,给定:const auto input = "Peas&Carrots Spinach-Casserole Beets Pizza Spinach-Salad Coleslaw"s,我想找到不包含“Spinach”的食物。所以我可以这样做:

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

当然问题在于,我得到了类似以下的输出

豌豆和胡萝卜

甜菜根
披萨

美式卷心菜沙拉

有没有什么解决方法?

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(); } 
);

1
你可以使用 std::copy_if 和 lambda 表达式来检查正则表达式匹配的字符串是否为空。使用方法:
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

实时演示

它只会打印非空字符串。


0

从比我更聪明的人的答案来看,似乎没有办法在没有lambda的情况下丢弃空结果。不过,在这个问题中有几个替代方案:

  1. 使用前瞻,这会稍微费一些时间,但只会捕获没有“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"));

实时示例

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

实时示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接