如果它们存在,如何有效地从std :: string中删除双引号

mol*_*ita 11 c++ stdstring

这个问题有可能是重复的,例如从c ++中的字符串中删除双引号, 但是我看到的所有asnwers都没有解决我的问题
我有一个字符串列表,其中一些是双引号而另一些则不是,引号总是在开头并结束

std::vector<std::string> words = boost::assign::list_of("words")( "\"some\"")( "of which")( "\"might\"")("be quoted");
Run Code Online (Sandbox Code Playgroud)

我正在寻找最有效的方法来删除报价.这是我的尝试

for(std::vector<std::string>::iterator pos = words.begin(); pos != words.end(); ++pos)
{
  boost::algorithm::replace_first(*pos, "\"", "");
  boost::algorithm::replace_last(*pos, "\"", "");
  cout << *pos << endl;
}
Run Code Online (Sandbox Code Playgroud)

我能做得比这更好吗?我可能有数十万个字符串要处理.它们可能来自文件或数据库.示例中的std :: vector仅用于说明目的.

Pot*_*ter 21

如果你知道报价将始终出现在第一个和最后一个位置,你可以做到

if ( s.front() == '"' ) {
    s.erase( 0, 1 ); // erase the first character
    s.erase( s.size() - 1 ); // erase the last character
}
Run Code Online (Sandbox Code Playgroud)

复杂性仍然是字符串大小的线性.您不能std::string在O(1)时间的开头插入或删除.如果用空格替换字符是可以接受的,那么就这样做.

  • 我认为这个答案比 Seth 更好,因为它更简单,分配成本更低。具体来说,Seth 将始终从 substr 调用中分配一个新字符串,而此中的 `s.erase(0,1)` 将原地复制字符。`s.erase(s.size()-1)` 会比 `s.pop_back()` 更具可读性,并且大约是两个赋值,所以可能可以忽略不计。 (2认同)

Set*_*gie 5

检查可能会很快:

for (auto i = words.begin(); i != words.end(); ++i)
    if (*(i->begin()) == '"')
        if (*(i->rbegin()) == '"')
            *i = i->substr(1, i->length() - 2);
        else
            *i = i->substr(1, i->length() - 1);
    else if (*(i->rbegin()) == '"')
        *i = i->substr(0, i->length() - 1);
Run Code Online (Sandbox Code Playgroud)

它可能不是最漂亮的东西,但它是一个小常数的O(n).

  • 如果你有C++ 11,你可以将丑陋的`*(i-> begin())`和`*(i-> rbegin())`更改为`i-> front()`和`i - >返回()`.更具可读性. (2认同)