fork(3) download
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <string>
  4. #include <regex>
  5. using namespace std;
  6.  
  7. template<class BidirIt, class Traits, class CharT, class UnaryFunction>
  8. std::basic_string<CharT> regex_replace(BidirIt first, BidirIt last,
  9. const std::basic_regex<CharT,Traits>& re, UnaryFunction f)
  10. {
  11. std::basic_string<CharT> s;
  12.  
  13. typename std::match_results<BidirIt>::difference_type
  14. positionOfLastMatch = 0;
  15. auto endOfLastMatch = first;
  16.  
  17. auto callback = [&](const std::match_results<BidirIt>& match)
  18. {
  19. auto positionOfThisMatch = match.position(0);
  20. auto diff = positionOfThisMatch - positionOfLastMatch;
  21.  
  22. auto startOfThisMatch = endOfLastMatch;
  23. std::advance(startOfThisMatch, diff);
  24.  
  25. s.append(endOfLastMatch, startOfThisMatch);
  26. s.append(f(match));
  27.  
  28. auto lengthOfMatch = match.length(0);
  29.  
  30. positionOfLastMatch = positionOfThisMatch + lengthOfMatch;
  31.  
  32. endOfLastMatch = startOfThisMatch;
  33. std::advance(endOfLastMatch, lengthOfMatch);
  34. };
  35.  
  36. std::sregex_iterator begin(first, last, re), end;
  37. std::for_each(begin, end, callback);
  38.  
  39. s.append(endOfLastMatch, last);
  40.  
  41. return s;
  42. }
  43.  
  44. template<class Traits, class CharT, class UnaryFunction>
  45. std::string regex_replace(const std::string& s,
  46. const std::basic_regex<CharT,Traits>& re, UnaryFunction f)
  47. {
  48. return regex_replace(s.cbegin(), s.cend(), re, f);
  49. }
  50.  
  51. std::string my_callback(const std::smatch& m) {
  52. if (m.str(1).length() % 2 == 0) {
  53. return m.str(1) + "(.+)";
  54. } else {
  55. return m.str(0);
  56. }
  57. }
  58.  
  59. int main() {
  60. std::string s = "abcd %1 %%2 %%%3 %%%%4 efgh\n\nabcd%12%%34%%%666%%%%11efgh";
  61. cout << regex_replace(s, regex("(%*)(\\d+)"), my_callback) << endl;
  62.  
  63. return 0;
  64. }
Success #stdin #stdout 0s 3500KB
stdin
Standard input is empty
stdout
abcd %1 %%(.+) %%%3 %%%%(.+) efgh

abcd%12%%(.+)%%%666%%%%(.+)efgh