string s = " 'I'd go.' ";
s = std::regex_replace(s, std::regex("((^| )')|('($| ))"), "$1(Quotation, )");
cout << s; // '(Quotation, )I'd go.(Quotation, )
I want to replace the ' with (Quotation, ), and I don't want to lose the original '. So, I use $1 to mean the original '. And I don't want to replace the ' of I'd.
^ means if the ' is at the start of the string it would be replaced.
$ means the end of the string.
The result is supposed to be:
'(Quotation, )I'd go.' (Quotation, )
But actually the result is
'(Quotation, )I'd go.(Quotation, )
The left quotation replacement works fine, but the right loses the '. Why?
It happens because the ' at the end of the string is captured in Group 3:
((^| )')|('($| ))
|| 2 | |
| 1 | | | 4 |
| 3 |
You may refer to each of the groups with $1, $2, $3 and $4, and more, you may even refer to the whole match using $& replacement backreferences.
So adding $3 can solve the issue:
s = std::regex_replace(s, std::regex("((^| )')|('($| ))"), "$1$3(Quotation, )");
// => '(Quotation, )I'd go.' (Quotation, )
See the C++ demo
An alternative solution might look like
s = std::regex_replace(s, std::regex("(?:^|\\s)'|'(?!\\S)"), "$&(Quotation, )");
The (?:^|\s)'|'(?!\S) regex matches
(?:^|\s)' - start of string or a whitespace char and a ' after them| - or'(?!\S) - a ' that is followed with a whitespace or end of string.The $& inserts the match back into the result upon a replacement. See this regex demo online (do not pay attention at the replacement there, the site does not support $& backreference).
NOTE: If you are using the latest compiler, you may use raw string literals when defining regexps, R"((?:^|\\s)'|'(?!\\S))".
You don't need several 'or's in your regex. Try this: ^\s*(').*(')\s*$
and replace the backreferences.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With