从字符串中删除空格,排除“和”C ++对之间的部分

时间:2015-10-31 15:01:29

标签: c++ string c++11 whitespace string-parsing

基本上我想要做的就是从std::string对象中删除所有空格,但不包括语音标记和引号内的部分(基本上是字符串),例如:

Hello, World! I am a string

会导致:

Hello,World!Iamastring

然而,语音标记/引号内的内容将被忽略:

"Hello, World!" I am a string

会导致:

"Hello, World!"Iamastring

或者:

Hello,' World! I' am a string

将是:

Hello,' World! I'amastring

是否有一个简单的例程来对字符串执行此操作,要么是构建到标准库中,要么是如何编写自己的字符串?它不一定是最有效的,因为它只会在程序运行时运行一次或两次。

4 个答案:

答案 0 :(得分:4)

,没有这样的常规准备就绪。

你可以建立自己的。

你必须循环遍历字符串,并且想要使用标志。如果该标志为true,则删除空格,如果为false,则忽略它们。

,当你不在引号的一部分时,该标志为真

这是一个天真的,没有广泛测试的例子:

#include <string>
#include <iostream>
using namespace std;

int main() {
    // we will copy the result in new string for simplicity
    // of course you can do it inplace. This takes into account only
    // double quotes. Easy to extent do single ones though!
    string str("\"Hello, World!\" I am a string");
    string new_str = "";
    // flags for when to delete spaces or not
    // 'start' helps you find if you are in an area of double quotes
    // If you are, then don't delete the spaces, otherwise, do delete
    bool delete_spaces = true, start = false;
    for(unsigned int i = 0; i < str.size(); ++i) {
        if(str[i] == '\"') {
            start ? start = false : start = true;
            if(start) {
                delete_spaces = false;
            }
        }
        if(!start) {
            delete_spaces = true;
        }
        if(delete_spaces) {
            if(str[i] != ' ') {
                new_str += str[i];
            }
        } else {
            new_str += str[i];
        }

    }
    cout << "new_str=|" << new_str << "|\n";
    return 0;
}

输出:

  

new_str = |“Hello,World!”Iamastring |

答案 1 :(得分:3)

我们走了。我最终迭代了字符串,如果找到"',它将翻转ignore标志。如果ignore标志为true且当前字符不是"',则迭代器只会递增,直到它到达字符串的末尾或找到另一个" / {{ 1}}。如果ignore标志为false,它将删除当前字符(如果它是空格,换行符或制表符)。

编辑:此代码现在支持忽略转义字符('\"),并确保以\'开头的字符串以"结尾,并且字符串以"开头,以'结尾,忽略其他任何内容。

'

答案 2 :(得分:2)

唉,在这里我花时间写这个(简单)版本:

#include <cctype>
#include <ciso646>
#include <iostream>
#include <string>

template <typename Predicate>
std::string remove_unquoted_chars( const std::string& s, Predicate p )
{
  bool skip = false;
  char q = '\0';
  std::string result;

  for (char c : s)
    if (skip) 
    {
      result.append( 1, c );
      skip = false;
    }
    else if (q)
    {
      result.append( 1, c );
      skip = (c == '\\');
      if (c == q) q = '\0';
    }
    else 
    {
      if (!std::isspace( c )) 
        result.append( 1, c );
      q = p( c ) ? c : '\0';
    }

  return result;
}

std::string remove_unquoted_whitespace( const std::string& s )
{
  return remove_unquoted_chars( s, []( char c ) -> bool { return (c == '"') or (c == '\''); } );
}

int main()
{
  std::string s;
  std::cout << "s? ";
  std::getline( std::cin, s );
  std::cout << remove_unquoted_whitespace( s ) << "\n";
}

删除由给定谓词标识的所有字符,除了内容在单引号或双引号C样式字符串中,注意尊重转义字符。

答案 3 :(得分:1)

你可以像这样使用擦除删除习语

#include <string>
#include <iostream>
#include <algorithm>


int main()
{
    std::string str("\"Hello, World!\" I am a string");

    std::size_t x = str.find_last_of("\"");
    std::string split1 = str.substr(0, ++x);
    std::string split2 = str.substr(x, str.size());

    split1.erase(std::remove(split1.begin(), split1.end(), '\\'), split1.end());

    split2.erase(std::remove(split2.begin(), split2.end(), ' '), split2.end());

    std::cout << split1 + split2;
}