2009-06-14 17 views
9

Kendimi şu anda C++ 'dan biraz kendim öğrenmeye çalışıyorum.
Python, perl, javascript'te çok deneyimliyim ama geçmişte bir sınıf ortamında sadece C++ ile karşılaştı. Lütfen sorumun naifini affedin.C++ düzenli bir ifade kullanarak bir dizgeyi belirtin

Normal bir ifade kullanarak bir dizeyi ayırmak istiyorum ancak 'u C++ 'da nasıl yapacağınıza dair net, kesin, verimli ve tam bir örnek bulma konusunda çok şansım olmadı.

, ben en iyi C++ eşdeğer gerçekleştirmek için bilmek istiyorum

/home/me$ cat test.txt 
this is aXstringYwith, some problems 
and anotherXY line with similar issues 

/home/me$ cat test.txt | perl -e' 
> while(<>){ 
> my @toks = split(/[\sXY,]+/); 
> print join(" ",@toks)."\n"; 
> }' 
this is a string with some problems 
and another line with similar issues 

Perlde bu eylem yaygındır ve dolayısıyla önemsiz bir şekilde gerçekleştirilebilir.

DÜZENLEME:
Aşağıda belirtildiği gibi destek kitaplığında aradığımı buldum.

boost regex-token-iterator (neden alt çizgiler çalışmaz?)

ben aramak bilmiyordum sanırım.


#include <iostream> 
#include <boost/regex.hpp> 

using namespace std; 

int main(int argc) 
{ 
    string s; 
    do{ 
    if(argc == 1) 
     { 
     cout << "Enter text to split (or \"quit\" to exit): "; 
     getline(cin, s); 
     if(s == "quit") break; 
     } 
    else 
     s = "This is a string of tokens"; 

    boost::regex re("\\s+"); 
    boost::sregex_token_iterator i(s.begin(), s.end(), re, -1); 
    boost::sregex_token_iterator j; 

    unsigned count = 0; 
    while(i != j) 
     { 
     cout << *i++ << endl; 
     count++; 
     } 
    cout << "There were " << count << " tokens found." << endl; 

    }while(argc == 1); 
    return 0; 
} 

+1

... söz o halde bunu buldum ve cevabı yayınladı. Birisi gelirse ve bu soruyu yararlı bulursa ... seçtikleri ile birlikte topluluğun cevabını görmek isterler. Cevabınız komünitlerin en iyi seçim olmayabilir. –

cevap

14

artırmak kütüphaneleri genellikle bu durumda Boost.Regex iyi bir seçimdir vardır. Hatta bir dizgiyi zaten istediğiniz şeyi yapan jetonlara bölmek için an example vardır. Temelde böyle bir şeye doğru geri gelir: Yineleyicilerin kullanımını en aza indirmek ve kodunuzu pithify istiyorsanız

boost::regex re("[\\sXY]+"); 
std::string s; 

while (std::getline(std::cin, s)) { 
    boost::sregex_token_iterator i(s.begin(), s.end(), re, -1); 
    boost::sregex_token_iterator j; 
    while (i != j) { 
    std::cout << *i++ << " "; 
    } 
    std::cout << std::endl; 
} 
+0

rebex_token_iterator'a kendi yolumu oberoi'nin yazısından bulduğum halde, bunu bir cevap olarak seçtim çünkü özlü, çalışır bir örnek veriyor ve uygun destek sayfasının bağlantısını içerir. şerefe. –

1

Perl'den farklı olarak, normal ifadeler C++ içine "yerleşik" değildir.

PCRE gibi bir dış kitaplık kullanmanız gerekir.

+0

bu, ayrıca 'bölünmüş' bir işlev içeriyor mu? python, dize bölme kolaylığı işlevleri sağlayan varsayılan bir normal ifade modülü olan 're' içerir. Bu aynı şekilde çalışırsa merak ediyorum? –

+0

Bu yanıt gönderildiğinde doğruydu, ancak artık C++ 11'in kullanılabilirliği ile doğru değil. #include ' – Justin

2

aşağıdaki çalışması gerekir:

#include <string> 
#include <iostream> 
#include <boost/regex.hpp> 

int main() 
{ 
    const boost::regex re("[\\sXY,]+"); 

    for (std::string s; std::getline(std::cin, s);) 
    { 
    std::cout << regex_replace(s, re, " ") << std::endl; 
    } 

}