Tam Nguyen
Tam Nguyen

Reputation: 1165

Replace a substring match with regex using C++

I use std::string regex_search and std::string regex_replace to find the substring and replace. My problem is that I don't know how to express it by my regular expression. When it comes to yy->%y the other case such as y, yyy,yyyy,yyyyy,etc..-> %Y

std::string text = "y yyaa";
std::regex y_re("[yY]+"); // this is the regex that matches y yyy or more yyyy
std::regex yy_re("(?=^y{2}[^y])y{2}"); // this is the regex that matches only yy- my problem is here
std::string output = "";
smatch m;

if (regex_search(text, m, yy_re)) {
    output = std::regex_replace(text, yy_re, "%y");
}
else {
    output = std::regex_replace(text, y_re, "%Y");
}
cout << output << endl;

My actual output :

%Y %Yaa

My expected output :

%Y %yaa

Upvotes: 1

Views: 813

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626923

You may play it safe and use more specific regex patterns to match 1) single y or Y or 3 or more y/Ys, or 2) only two y/Ys:

std::string text = "y yyaa";
std::regex y_re("([^yY%]|^)[yY](?![yY])|[yY]{3,}"); // this is the regex that matches y yyy or more yyyy
std::regex yy_re("([^yY%]|^)[yY]{2}(?![yY])"); // this is the regex that matches only yy- my problem is here
std::string output = "";

output = std::regex_replace(text, yy_re, "$1%y");
output = std::regex_replace(output, y_re, "$1%Y");
std::cout << output << std::endl;

See the online C++ demo.

You may use this approach even when the order of replacements is not known.

Regex details

  • Regex 1 matches only a single or 3 or more consecutive y / Ys:
    • ([^yY%]|^)[yY](?![yY]) - Group 1: start of string or any char other than y, Y and %, then a Y or y and then no y nor Y is allowed
    • | - or
    • [yY]{3,} - three or more y / Ys

Regex #2 works similarly, just [yY]{2} matches only two y or Y chars.

The replacement contains a backreference to the Group 1 value to put back the captured char.

Upvotes: 1

Related Questions