替换字符串中的空格

Replace space in string

本文关键字:空格 字符串 替换      更新时间:2023-10-16

我不太擅长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()); 

但这会删除行中的所有污点。

我正在使用一个编译器:

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

它没有regex标头

您可以在代码中使用库regex,也可以使用在perl中使用的regex

有关正则表达式库的信息

编辑:

如果你没有c++11,你可以看看boost,看看下面的链接:Boost库(正则表达式部分)

如果Boost是一个选项,您应该能够像这样使用正则表达式。

否则,您可以简单地在字符串中运行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;   
}

测试。

这很棘手,我在经历这件事时发现了一些问题:

  1. 如果在每个循环中以某种循环的方式迭代字符串,则需要擦除或增加迭代器。不要同时执行这两项操作,您将擦除一个值,然后跳过一个值
  2. 注意这里的迭代器,确保不要试图访问任何超出范围的内容,特别是如果你检查前后的值是否是字母,你必须从一个开头开始,在结尾之前停止,然后独立检查开头的那个,我认为结尾的那个应该没问题,因为有了离端迭代器
  3. 这个逻辑可能也有点令人困惑,有点像双重否定。那些没有被字母包围的就不会被放在身边

我尽量避免使用c++11,但强烈建议使用它,因为键入auto比字符串::迭代器要好得多。它确实按照你键入的内容生成了文本,这看起来也相当简单。

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

我已经用堆栈完成了。你所做的是初始化一个堆栈,然后忽略空格,当你遇到一个字符时,你推送字符,直到出现',',推送后,你弹出所有空格,直到出现一个字符(请参阅下面我所做的其他部分的程序),然后你从堆栈中的元素组成一个字符串,并反转你需要回答的字符串。如果有人在这件事上做错了什么,请告诉我

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

没有regex的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))