Kam
Kam

Reputation: 6008

Is there a standard C++11 solution to escape single quotes?

I have been looking around for a solution to escape single quotes in a std::string, without finding a clean way to do it.

This post gives few solutions like this one:

std::wstring regex_escape(const std::wstring& string_to_escape) {
    static const boost::wregex re_boostRegexEscape( _T("[\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\\\]") );
    const std::wstring rep( _T("\\\\\\1&") );
    std::wstring result = regex_replace(string_to_escape, re_boostRegexEscape, rep, boost::match_default | boost::format_sed);
    return result;
}

Quite cool but too complicated for my requirement. Is there an easier, more understandable (and standard) way to solve this problem (without hitting performance)?

Note: maybe I am finding the above too compicated because I don't really understand what this line is doing: const std::wstring rep( _T("\\\\\\1&") )

Upvotes: 1

Views: 3759

Answers (1)

Alexis Wilke
Alexis Wilke

Reputation: 20771

I'm quite impressed by the very large number of people who will give an answer using Regular Expressions to do something extremely simple such as escaping one character in a string. You mentioned performance, using regular expressions is definitively not going to be fast unless you have a rather complicated test to perform before the transformation or if your end users is in control of the transformation (i.e. they have to write the regex.)

Frankly, in this case you should just write it with a simple loop:

 std::string result;
 size_t const len(input.length());
 result.reserve(len + 10);  // assume up to 10 single quotes...
 for(size_t idx(0); idx < len; ++idx)
 {
     if(input[idx] == '\'')
     {
          result += "\\\'";
     }
     else
     {
          result += input[idx];
     }
 }

This is likely to give you the best performance. Yeah, it's not just one simple function call... some people would search for '\'' with find(), the scanning would be very close to this scanning, but copying a substr() generally costs more than copying the characters as you scan.

Note that if you are using boost there is a replace_all() function in there which you could use too. It would be cleaner, but you did not mention boost... There is an answer with replace_all() (among other solutions):

How to find and replace string?

Upvotes: 5

Related Questions