除非已经转义,否则如何替换字符串或字符的所有出现?

yha*_*ger 5 c++ string boost

是否有一个漂亮而优雅的方式(使用boost :: algorithm :: replace may?)来替换字符串中所有出现的字符 - 除非前面加一个反斜杠?

以便

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''"
Run Code Online (Sandbox Code Playgroud)

使用boost :: regex,可以使用以下命令完成:

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);
}
Run Code Online (Sandbox Code Playgroud)

但由于性能原因,我不想使用boost :: regex.boost :: algorithm :: replace看起来很合适,但我无法确切知道如何.

And*_*owl 3

这是一个完成这项工作的简单算法:

#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'");
}
Run Code Online (Sandbox Code Playgroud)

更新:

按照@BenVoigt的建议,我重新制定了算法以避免就地操作。这应该会带来进一步的性能提升:

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;
}
Run Code Online (Sandbox Code Playgroud)