c++regexc++11regex-replace

Replace nth regex match in C++


I've found this topic which only explains how to replace the first regex match. What about some n'th match?

Say I have a string and a regex like these:

std::string str  = "fast cast dust crust must last rust";
std::regex  expr = " .(a|u)st";

How can I replace, say, the third match with some other sequence? std::regex_replace allows to replace either all matches or the first one. I'm also thinking about std::regex_iterator, but still can't figure out how to apply it in this task. What are the most convenient ways to solve the problem?


Solution

  • I've managed to come up with my own solution. I use std::string::replace taking a pair of iterators in the first std::sub_match from the advanced std::sregex_iterator:

    std::string str = "fast cast dust crust must last rust";
    std::regex expr{" .(a|u)st"};
    std::sregex_iterator regex_it{str.cbegin(), str.cend(), expr};
    
    std::advance(regex_it, 2);
    str.replace(regex_it->cbegin()->first, regex_it->cbegin()->second, " lol");
    std::cout << str << std::endl;
    

    One could add some extra iterator validations if they wish. I'll keep it brief.

    The output is:

    fast cast dust crust lol last rust
    

    It's worth mentioning, however, that std::regex_replace returns a modified copy whereas the solution above changes the string in place. Also, one should be careful as the iterators in the sub_matches may become invalidated once the replacement has been completed.