0

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

没有正则表达式标头

4

5 回答 5

2

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

有关正则表达式库的信息

编辑:

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

于 2013-07-01T13:51:02.697 回答
1

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

测试

于 2013-07-01T15:04:17.047 回答
1

这很棘手,我在经历这个时发现了一些事情:

  1. 如果您在每个循环中以某种循环遍历字符串,则需要擦除或增加迭代器。不要两者都做,你会删除一个值,然后跳过一个值。
  2. 在此处查看迭代器,确保不要尝试访问超出范围的任何内容,特别是如果您要检查之前和之后的值是否为字母,则必须从开头开始,在结尾之前停止,然后独立检查开头的那个,我认为结尾的那个应该没问题,因为结束了迭代器。
  3. 逻辑也可能有点混乱,有点像双重否定。那些没有被字母包围的不会被保留。

我试图避免使用 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;
}
于 2013-07-01T16:54:19.153 回答
1

我已经使用堆栈完成了它。你所做的是初始化一个堆栈并且你有空格忽略,当你遇到一个字符时你推送字符直到出现',',然后推送你弹出所有空格直到一个字符出现(请参阅下面我已完成的其他部分的程序)然后您从堆栈中的元素形成一个字符串并反转您需要回答的字符串。如果任何机构在这方面有任何问题,请告诉我

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

}
于 2013-07-01T18:29:07.140 回答
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))
于 2013-07-01T15:40:08.337 回答