boost::optional<std::string>
find_word_with(std::string const& haystack, std::string const& needle) {
std::istringstream ss (haystack);
for (std::string word; ss >> word;) {
if (word.find(needle) != word.npos) {
return boost::optional<std::string>(word);
}
}
return boost::optional<std::string>();
}
std::string const whitespace = " \t\r\n\v\f";
boost::optional<std::string>
find_word_with2(std::string const& haystack, std::string const& needle) {
typedef std::string::size_type Pos;
Pos found = haystack.find(needle);
if (found == haystack.npos) {
return boost::optional<std::string>();
}
Pos start = haystack.find_last_of(whitespace, found);
if (start == haystack.npos) start = 0;
else ++start;
Pos end = haystack.find_first_of(whitespace, found+1);
if (end == haystack.npos) end = haystack.length();
return boost::optional<std::string>(haystack.substr(start, end - start));
}
Оба эти только отдельные слова в пробеле (я пропустил, что вы сначала хотели «xyzwy» вместо «xyzwy!»), Но вы могли изменить их так, чтобы игнорировать знаки препинания. Первое не очень поддается этому, но второе можно легко изменить, чтобы использовать find_first / last_ , а не _of с эквивалентом регулярного выражения \w
("ABC..abc ..012 .._ ") вместо проверки пробелов.
Обратите внимание, что вторая, использующая жестко закодированную переменную whitespace , не учитывает локали, как потоковое решение (которое использует последний установленный глобальный языковой стандарт), но может быть именно тем, что вам нужно.
int main() {
{
boost::optional<std::string> r =
find_word_with("Hi xyzwy! what are you doing here?", "w");
if (!r) std::cout << "not found\n";
else std::cout << "found: " << *r << '\n';
}
{
boost::optional<std::string> r =
find_word_with2("Hi xyzwy! what are you doing here?", "w");
if (!r) std::cout << "not found\n";
else std::cout << "found: " << *r << '\n';
}
return 0;
}