2013-07-01 176 views
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()); 

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

我使用的编译器:

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

不具有正则表达式头

+0

[boost](http://stackoverflow.com/questions/11321533/how-to-use-boost-regular-expression-r E放置方法)? – Dukeling

+0

可能的重复http://stackoverflow.com/questions/5891610/how-to-remove-characters-from-a-string –

+0

而这里http://stackoverflow.com/questions/236129/splitting-a-string- in-c – doctorlove

回答

2

您可以使用该库正则表达式在你的代码,并使用您在Perl中使用正则表达式

Information about regex library

编辑:

如果y OU没有C++ 11比你可以看看提振,看看下面的链接: Boost library (regex section)

+0

请参阅我的编辑!我没有用我的编译器 – user1939168

+0

正则表达式he4ader看看下面的boost库:http://www.boost.org/doc/libs/1_53_0/libs/regex/doc/html/boost_regex/ref/regex_replace.html – Bjorn

+1

@ user1939168你可能没有'std :: regex',但你可以使用'boost :: regex'(虽然这是一个非常痛苦的安装)。或者,由于您使用的是Sun CC,因此您可能位于Unix平台上; Unix定义了一个''标题,虽然它比Boost或标准更不舒服,但它仍然是一个开始。 –

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

+0

如果在单词之间存在多于1个空格,则C++版本将不起作用。 –

+0

你说得对,我应该检查输出字符串,而不是输入字符串,固定。谢谢。 – Dukeling

0

没有正则表达式A 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)) 
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; 
} 
1

我已经做到了用stack.What你要做的就是初始化堆栈和你的空间忽略,当你遇到一个字符U推字符,直到“”出现,并推后你弹出所有的空间,直到一个字符已经发生(见下面的程序,在我已经完成的其他部分)之后,你从堆栈中的元素形成一个字符串,并反向字符串,你将需要answer.If任何身体有任何错误,请让我知道

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

}