wrongElk
wrongElk

Reputation: 91

Conditional replace using regex

I need some help with formatting strings using regex. I have a string of type

(33,2),(44,2),(0,11)

I have to reformat this string to the following

(2),(2),(0,11)

That is, remove (\\([[:digit:]]+\\,) from the input except for the last occurrence.

I tried the following code, but it replaces all occurrences.

#include <iostream>
#include <string>
#include <regex>

int main ()
{
  std::string s ("(32,33),(63,22),(22,1)");
  std::regex e ("[[:digit:]]+\\,"); 
  std::string result;

  std::regex_replace (std::back_inserter(result), s.begin(), s.end(), e, "$2");
  std::cout << result;

  return 0;
}

I understand that I need to use std::sregex_iterator to get this done but haven't been able to figure this out.

Appreciate all help.

Upvotes: 1

Views: 173

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626920

You may match these digits only if they are followed with (:

[[:d:]]+,(?=.*\()

Details:

  • [[:d:]]+ - 1 or more digits
  • , - a comma
  • (?=.*\\() - a positive lookahead requiring a ( after any 0+ chars other than linebreak chars.

The positive lookahead here can be replaced with a negtive (?![[:d:]]+\\)$) lookahead to fail all matches of the digits+, if they are followed with 1+ digits + ) at the end of the string.

See C++ demo:

#include <iostream>
#include <string>
#include <regex>

int main ()
{
  std::string s ("(32,33),(63,22),(22,1)");
  std::regex e ("[[:d:]]+,(?=.*\\()"); 
  std::string result;

  std::regex_replace (std::back_inserter(result), s.begin(), s.end(), e, "$2");
  std::cout << result;

  return 0;
}

Upvotes: 1

Related Questions