Есть ли способ отбросить пустые записи?

Есть ли встроенный способ перебирать только непустые перехваты или мне нужно использовать лямбду / модифицировать мое регулярное выражение?

Например, учитывая: 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"));

Проблема, конечно, в том, что Я получаю вывод лайк:

Горох&морковь

Свеклу
Пицца

капустный салат

Это можно обойти?

3

Решение

Ты можешь использовать 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

Живой пример

Так как он будет печатать только непустые строки.

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

Из ответов тех, кто мудрее меня, кажется, что на самом деле нет способа отбросить пустые результаты без лямбды. В этом вопросе есть несколько альтернатив:

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

Живой пример

  1. Используйте 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; });

Живой пример

0
По вопросам рекламы [email protected]