Есть ли встроенный способ перебирать только непустые перехваты или мне нужно использовать лямбду / модифицировать мое регулярное выражение?
Например, учитывая: 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"));
Проблема, конечно, в том, что Я получаю вывод лайк:
Горох&морковь
Свеклу
Пиццакапустный салат
Это можно обойти?
Ты можешь использовать 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
Так как он будет печатать только непустые строки.
Очевидным способом было бы использовать 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(); }
);
Из ответов тех, кто мудрее меня, кажется, что на самом деле нет способа отбросить пустые результаты без лямбды. В этом вопросе есть несколько альтернатив:
const regex re{ "(?:\\s+|^)(?!Spinach)(\\S+)" };
copy(sregex_token_iterator(cbegin(input), cend(input), re, 1), sregex_token_iterator(), ostream_iterator<string>(cout, "\n"));
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; });