替换字符串中的空格

时间:2013-07-01 13:48:44

标签: c++ string

我对C ++ STL不太满意。 我有这样的字符串:

   x  ,y z  ,  a ,b, some text ,

除了两个单词之间的空格外,我希望除去此处的所有空格 所以我希望输出为:

x,y z,a,b,some text,

我可以在perl中轻松地执行此操作:

perl -pe 's/\s*,\s*/,/g;s/^\s*//g'

但我需要用C ++。

到目前为止我能做的是:

line.erase(remove_if(line.begin(), line.end(), isspace), line.end()); 

但这会删除该行中的所有splaces。

我正在使用编译器:

> CC -V
CC: Sun C++ 5.9 SunOS_i386 Patch 124864-01 2007/07/25

没有正则表达式标题

5 个答案:

答案 0 :(得分:2)

您可以在代码中使用库正则表达式并使用您在perl中使用的正则表达式

Information about regex library

编辑:

如果您没有c ++ 11而不是看看boost,请查看以下链接: Boost library (regex section)

答案 1 :(得分:1)

如果Boost是一个选项,您应该可以使用正则表达式like this

否则,您只需在字符串中运行for循环,并跳过下一个或上一个字符为逗号或空格的空格:

#include <iostream>
#include <string>

using namespace std;

bool isCommaOrSpace(char c)
{
   return c == ' ' || c == ',';
}

int main()
{
   string source = "   x  ,y  z  ,  a ,b, some text , ";
   string result = "";
   char last = ' ';
   for (unsigned int i=0; i<source.length(); i++)
   {
      if (source[i] != ' ' ||
          (!isCommaOrSpace(last) &&
           i < source.length()-1 && !isCommaOrSpace(source[i+1])))
      {
         result += source[i];
         last = source[i];
      }
   }

  cout << result << endl;

  int len;
  cin >> len;
  return 0;   
}

Test

答案 2 :(得分:1)

这很棘手,我在解决这个问题时想到了一些事情:

  1. 如果你在每个循环中在某种循环中迭代字符串,则需要擦除或增加迭代器。不要同时执行这两项操作,您将删除一个值,然后跳过一个值。
  2. 在这里观察迭代器,请确保不要尝试访问范围之外的任何内容,特别是如果您要检查前后的值是否为字母,则必须在开头之前开始一个并在结束之前停止一个然后在开头独立检查一个,我觉得最后一个应该没问题,因为关闭了迭代器。
  3. 逻辑可能有点混乱,有点像双重否定。没有被字母包围的那些不被保留。
  4. 我试图避免使用c ++ 11,但强烈推荐它,键入auto比使用string :: iterator更好。它确实按照您输入的方式生成文本,这看起来也很简单。

    #include <iostream>
    #include <string>
    #include <cctype>
    using namespace std;
    
    int main()
    {
    string mytext = "   x  ,y z  ,  a ,b, some text ,";
    string::iterator it = (mytext.begin() + 1);
    while(it != (mytext.end() - 1))
    {
    if(*it == ' ' && !(isalpha(*(it-1)) && isalpha(*(it+1))))
    mytext.erase(it);
    else
    ++it;
    }
    if(*(mytext.begin()) == ' ')
    mytext.erase(mytext.begin()); 
    
    cout << "x,y z,a,b,some text," << endl;
    cout << mytext << endl;
    return 0;
    }
    

答案 3 :(得分:1)

我已经使用stack完成了它。你做的是初始化一个堆栈,你有空格忽略,当你遇到一个角色时你按下字符直到','出现,并在你推动之后弹出所有空格直到一个角色出现(参见下面的程序,在其他部分我已经完成)然后你从堆栈中的元素形成一个字符串并反转你需要回答的字符串。如果任何身体有任何错误,请让我们我知道

#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;
void remove(stack<char> &mystack,int &i,string s)
{

while(s[i]!=',')
{
    int v;

    mystack.push(s[i]);
    i++;
}
}
int main()
{
string s = "   x  ,y  z  ,  a ,b, some text , ";
string r,str;
stack<char> mystack;

int i=0;
while(i<s.length())
{

    if(s[i]==' ')
    {

    i++;

}
    else if(s[i]==',')
{
    mystack.push(s[i]);
    i++;
}
    else 
    {
        remove(mystack,i,s);

    char c=mystack.top();
    while(c==' ')
    {
        mystack.pop();
        c=mystack.top();

    }

}

}

    while(!mystack.empty())
    {
        char c=mystack.top();
        str=str+c;
        mystack.pop();


    }
    reverse(str.begin(),str.end());
    cout<<str;

}

答案 4 :(得分:0)

没有正则表达式的C ++实现可能如下所示(基于上面的字符串示例):

for (size_t pos = 1; pos < line.size() - 1; pos = line.find (' ', pos+1))
    if (line[pos-1] == ',' || line[pos-1] == ' ' || line[pos+1] == ',' || line[pos+1] == ' ')
    {
        line.erase(pos, 1);
        --pos;
    }
if (line[0] == ' ')
    line.erase(0, 1);
if (line[line.size() - 1] == ' ')
    line.erase(line[line.size() - 1], 1);  //line.pop_back() for C++11

你也可以在第二行使用std :: isalpha():

std::locale loc;
//...
    if (!std::isalpha(line[pos-1], loc) && !std::isalpha(line[pos+1], loc))