Is there a nice and elegant way (using boost::algorithm::replace maybe?) to replace all occurrences of a character in a string - unless preceded by a backslash?
so that
std::string s1("hello 'world'");
my_replace(s1, "'", "''"); // s1 becomes "hello ''world''"
std::string s2("hello \\'world'"); // note: only a single backslash in the string
my_replace(s2, "'", "''"); // s2 becomes "hello \\'world''"
Using boost::regex, this can be done using:
std::string my_replace (std::string s, std::string search, std::string format) {
boost::regex e("([^\\\\])" + search);
return boost::regex_replace(s, e, "\\1" + format);
}
But I prefer not to use boost::regex due to performance reasons. boost::algorithm::replace looks like a good fit, but I can't figure out exactly how.
Here is a simple algorithm that does the job:
#include <iostream>
#include <string>
using namespace std;
string replace(char c, string replacement, string s)
{
string chars = string("\\") + c;
size_t pos = s.find_first_of(chars);
while (pos != string::npos)
{
char& ch = s[pos];
if (ch == '\\')
{
pos = s.find_first_of(chars, pos + 2);
}
else if (ch == c)
{
s.replace(pos, 1, replacement);
pos = s.find_first_of(chars, pos + replacement.length());
}
}
return s;
}
int main()
{
cout << replace('\'', "''", "hello \\'world'");
}
UPDATE:
Following @BenVoigt's suggestion, I reformulated the algorithm to avoid in-place operations. That should bring further performance improvement:
string replace(char c, string replacement, string const& s)
{
string result;
size_t searchStartPos = 0;
string chars = string("\\") + c;
size_t pos = s.find_first_of(chars);
while (pos != string::npos)
{
result += s.substr(searchStartPos, pos - searchStartPos);
if (s[pos] == '\\')
{
result += string("\\") + c;
searchStartPos = pos + 2;
}
else if (s[pos] == c)
{
result += replacement;
searchStartPos = pos + 1;
}
pos = s.find_first_of(chars, searchStartPos);
}
return result;
}
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