2
\$\begingroup\$

This is a version of C++17 regex_replace that handles arbitrary functions to do the replacement, instead of using regex_replace's weird minigame language ($&, $', and $`). Also, I made it take string_view instead of const string&; that's more to see if people have opinions on string_view than for any practical reason. :) (The standard C++17 regex library is not aware of the existence of string_view.)

template<class F>
std::string regex_replace(std::string_view haystack,
                          const std::regex& rx, const F& f)
{
    std::string result;
    const char *begin = haystack.data();
    const char *end = begin + haystack.size();
    std::cmatch m, lastm;
    if (!std::regex_search(begin, end, m, rx)) {
        return std::string(haystack);
    }
    do {
        lastm = m;
        result.append(m.prefix());
        result.append(f(m));
        begin = m[0].second;
        begin += (begin != end && m[0].length() == 0);
        if (begin == end) break;
    } while (std::regex_search(begin, end, m, rx,
        std::regex_constants::match_prev_avail));
    result.append(lastm.suffix());
    return result;
}

void test()
{
    auto s = "std::sort(std::begin(v), std::end(v))";
    auto t = regex_replace(s, std::regex("\\bstd::(\\w+)"),
        [](auto&& m) { return m[1]; });
    assert(t == "sort(begin(v), end(v))");

    auto u = regex_replace(s, std::regex("\\bstd::(\\w+)"),
        [](auto&& m) { return "my::" + m.str(1); });
    assert(u == "my::sort(my::begin(v), my::end(v))");

    auto v = regex_replace(s, std::regex("\\bstd::(\\w+)"),
        [](auto&& m) {
            std::string result;
            std::transform(m[1].first, m[1].second, back_inserter(result), ::toupper);
            return result;
        });
    assert(v == "SORT(BEGIN(v), END(v))");
}

Any bugs in regex_replace? Any way to shorten it up? Any way to reuse the standard regex_iterator or regex_token_iterator would be greatly appreciated.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.