是否有标准的 C++11 解决方案来转义单引号?

Kam*_*Kam 1 c++ regex boost c++11

我一直在寻找一种在 std::string 中转义单引号的解决方案,但没有找到一种干净的方法来做到这一点。

这篇文章给出了几个这样的解决方案:

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

很酷但对我的要求来说太复杂了。有没有更简单、更容易理解(和标准)的方法来解决这个问题(不影响性能)?

注意:也许我发现上面的内容太复杂了,因为我真的不明白这条线在做什么: const std::wstring rep( _T("\\\\\\1&") )

Ale*_*lke 5

很多人会使用正则表达式来做一些非常简单的事情,例如转义字符串中的一个字符,这给我留下了深刻的印象。您提到了性能,使用正则表达式肯定不会很快,除非您在转换之前要执行相当复杂的测试,或者如果您的最终用户控制转换(即他们必须编写正则表达式)。

坦率地说,在这种情况下,您应该只用一个简单的循环来编写它:

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

这很可能会为您提供最佳性能。是的,这不仅仅是一个简单的函数调用……有些人会用 find() 搜索 '\'',扫描将非常接近这种扫描,但是复制一个substr()通常比扫描时复制字符的成本更高。

请注意,如果您使用的是 boost replace_all(),那么您也可以使用其中的一个函数。它会更干净,但你没有提到提升......有一个答案replace_all()(在其他解决方案中):

如何查找和替换字符串?

  • 部分性能方面是字符串转义函数很少需要做任何事情,所以它们应该针对没有什么可以转义的情况进行优化。`string::find` 很可能会使用 SSE 并行执行多达 16 次比较,因此它可能会比测试和复制循环更快地拒绝没有撇号的字符串。但是,为了正确利用这一点,您需要一个“就地”API。转换并没有真正就地完成——新的字符串被交换——但如果没有什么可做的,身份转换是就地的。 (2认同)