Use iterators in search::context() and don't return extra whitespace

Should be easier to understand now.
This commit is contained in:
tastytea 2021-05-30 13:31:59 +02:00
parent ded11af5fb
commit d7ad180721
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
1 changed files with 44 additions and 22 deletions

View File

@ -22,6 +22,7 @@
#include <boost/regex.hpp>
#include <algorithm>
#include <array>
#include <string>
#include <string_view>
#include <vector>
@ -181,49 +182,70 @@ match_context context(const boost::match_results<string::const_iterator> &match,
return {};
}
const auto &prefix{match.prefix().str()};
const auto &suffix{match.suffix().str()};
size_t pos_before{prefix.length()};
size_t pos_after{};
++words;
const auto &rbegin_before{std::reverse_iterator(match.prefix().end())};
const auto &rend_before{std::reverse_iterator(match.prefix().begin())};
const auto &begin_after{match.suffix().begin()};
const auto &end_after{match.suffix().end()};
auto pos_before{rbegin_before};
auto pos_after{begin_after};
const std::array<char, 4> whitespace{' ', '\n', '\r', '\t'};
auto is_whitespace{
[&whitespace](char check)
{
return std::any_of(whitespace.begin(), whitespace.end(),
[&check](const char ws) { return check == ws; });
}};
while (words != 0)
{
if (pos_before != 0)
if (pos_before != rend_before)
{
pos_before = prefix.rfind(' ', pos_before);
if (pos_before != string::npos)
pos_before = std::find_first_of(pos_before, rend_before,
whitespace.begin(),
whitespace.end());
if (pos_before != rend_before)
{
--pos_before;
}
else
{
pos_before = 0;
while (is_whitespace(*pos_before))
{
++pos_before;
}
}
}
if (pos_after != string::npos)
if (pos_after != end_after)
{
pos_after = suffix.find(' ', pos_after);
if (pos_after != string::npos)
pos_after = std::find_first_of(pos_after, end_after,
whitespace.begin(),
whitespace.end());
if (pos_after != end_after)
{
++pos_after;
while (is_whitespace(*pos_after))
{
++pos_after;
}
}
}
words -= 1;
}
if (pos_before != 0)
const std::string prefix_reversed(rbegin_before, pos_before);
string prefix(prefix_reversed.rbegin(), prefix_reversed.rend());
std::string suffix(begin_after, pos_after);
while (is_whitespace(*prefix.begin()))
{
pos_before += 2;
prefix.erase(0, 1);
}
if (pos_after != string::npos)
while (is_whitespace(*suffix.rbegin()))
{
pos_after -= 1;
suffix.erase(suffix.size() - 1);
}
return {prefix.substr(pos_before), suffix.substr(0, pos_after)};
return {prefix, suffix};
}
string headline(const std::string_view prefix)