2009-06-14 15 views
9

Estoy tratando de aprender C++ desde cero en este momento.
Soy muy versado en python, perl, javascript pero solo he encontrado C++ brevemente, en un entorno de clase en el pasado. Disculpe la ingenuidad de mi pregunta.C++ tokenize una cadena usando una expresión regular

Me gustaría dividir una cadena utilizando una expresión regular, pero no he tenido mucha suerte en encontrar un claro, definitivo, eficiente y completo ejemplo de cómo hacer esto en C++.

en Perl esta es la acción es común, y por lo tanto se puede lograr de una manera trivial,

/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 

Me gustaría saber cuál es la mejor para llevar a cabo el equivalente en C++.

EDIT:
Creo que encontré lo que estaba buscando en la biblioteca de impulso, como se menciona a continuación.

boost regex-token-iterator (¿por qué no funcionan guiones?)

supongo que no sabía qué buscar.


#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

debe agregar el "que se encuentra en mi propia" parte como una respuesta a su propia pregunta en lugar de tener que ser parte de su pregunta ... aunque mención que encontré y publicó la respuesta. si aparece alguien más y encuentra útil esta pregunta ... querrán ver la respuesta seleccionada de la comunidad junto con la elegida. Tu respuesta podría no ser la mejor opción para las comunidades. –

Respuesta

14

Las bibliotecas Boost suelen ser una buena opción, en este caso Boost.Regex. Incluso hay an example para dividir una cadena en tokens que ya hace lo que desea. Básicamente se trata de algo como esto:

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

aunque encontré mi propio camino para regex_token_iterator desde la publicación de oberoi, elegí esto como una respuesta porque ofrece un ejemplo conciso y funcional, e incluye el enlace a la página de impulso adecuada. aclamaciones. –

1

diferencia en Perl, las expresiones regulares no son "construidos en" en C++.

Necesita utilizar una biblioteca externa, como PCRE.

+0

¿Esto también contiene una función 'dividir'? python contiene un módulo de expresiones regulares predeterminado, 're', que proporciona funciones de conveniencia de división de cadenas. Me pregunto si esto funciona de la misma manera? –

+0

Esta respuesta fue verdadera cuando se envió, pero ya no es cierta con la disponibilidad de C++ 11. '#include ' – Justin

3

Eche un vistazo a Boost.Regex. Creo que se puede encontrar su respuesta aquí:

C++: what regex library should I use?

+0

gracias, encontré mi camino a regex_token_iterator de esto. –

2

Si desea reducir al mínimo el uso de iteradores, y pithify su código, lo siguiente debería funcionar:

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

} 
Cuestiones relacionadas