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

时间:2011-09-11 14:34:58

标签: c++ stdstring

这个问题有可能重复,例如remove double quotes from a string in c++ 但是我所看到的任何一个因素都没有解决我的问题 我有一个字符串列表,其中一些是双引号,一些不是,引号总是在开头和结尾

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

我正在寻找删除引号的最有效方法。这是我的尝试

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;
}

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

3 个答案:

答案 0 :(得分:20)

如果您知道引号将始终显示在第一个和最后一个位置,则可以执行

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

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

答案 1 :(得分: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);

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

答案 2 :(得分:-2)

这就是我接近这种情况的方式:

  • 开始简单:从最简单的方法开始,就像Potatoswatter的回答一样。
  • 不存储带引号的字符串:如果可以提供帮助,请不要存储带引号的字符串。在首先创建std::vector<std::string>的位置检查和取消引用字符串。如果您只是收到一个std::vector<std::string>,那么您可以做的太多了,因为删除第一个引号将需要复制其余的字符串。
  • 个人资料/基准测试:您可能会惊讶地发现几个100000字符串的迭代速度以及任何数量的微优化最终会让您获得多少。在某些情况下,您确实需要一点点速度,但要确保了解如何获得最大的收益(分析会告诉您)。
  • 最坏情况:如果您在取消引用时必须防止复制整个字符串,则将索引/迭代器存储到第一个“真实”字符。对于“短”字符串,这实际上可能更慢,但可以使用“长”字符串(即,大小为兆字节)。您还可以创建或查找一个字符串类来处理移动字符串start而不复制,但这将是我的最后选择。