2013-07-01 177 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; 

}