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;
        begin = m[0].second;
        begin += (begin != end && m[0].length() == 0);
        if (begin == end) break;
    } while (std::regex_search(begin, end, m, rx,
    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.


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.