I'd do it by avoiding using the regex
, cause once you introduce a regex
, Now you have 2 problems
Given:
- The beginning of our search range:
const auto first = "Somebody"s
- The end of our search range:
const auto second = "words"s
- The collection of words that shouldn't exist in the range:
const vector<string> words = { "in"s }
- The input string:
const auto input = "Somebody has typed in some words here."s
We can do this:
const auto start = input.find(first) + size(first);
const auto finish = input.find(second, start);
if (start != string::npos && finish != string::npos) {
istringstream range(input.substr(start, finish - start));
if (none_of(istream_iterator<string>(range), istream_iterator<string>(), [&](const auto& i) { return find(cbegin(words), cend(words), i) != cend(words); })) {
cout << "match\n";
} else {
cout << "not a match\n";
}
} else {
cout << "not a match\n";
}
Live Example
If you're married to a regex
though, there is a way that you can do this using a regex
. For example if words
contained: "in", "lorem", and "ipsum" you'd want something like:
\bSomebody\b(?:(\bin\b|\blorem\b|\bipsum\b).*|.)*?\bwords\b
Then we'd just need to test if our match contained anything:
const regex re("\\b" + first + accumulate(next(cbegin(words)), cend(words), "\\b(?:(\\b" + words.front(), [](const auto& lhs, const auto& rhs) { return lhs + "\\b|\\b" + rhs; }) + "\\b).*|.)*?\\b" + second + "\\b");
smatch sm;
if (regex_search(input, sm, re) && sm[1].length() == 0U) {
cout << "match\n";
} else {
cout << "not a match\n";
}
Live Example