Search code examples
c++regexstringiteratorspinach

Is There a Way to Discard Empty Captures?


Is there a built in way to iterate over non-empty captures only or do I need to use a lambda/modify my regex?

For example, given: const auto input = "Peas&Carrots Spinach-Casserole Beets Pizza Spinach-Salad Coleslaw"s I'd like to find foods that don't contain "Spinach". So I can do this:

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

The problem of course is that I get an output like:

Peas&Carrots

Beets
Pizza

Coleslaw

Is there a way around this?


Solution

  • You can use std::copy_if and a lambda to check that the string from the regex match is empty or not. Using

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

    We get

    Peas&Carrots
    Beets
    Pizza
    Coleslaw
    

    Live Example

    As it will only print non-empty strings.