2011-04-27 31 views
7

Estoy tratando de tomar una cadena en C++ y encontrar todas las direcciones IP contenidas en el interior, y ponerlas en una nueva cadena de vectores.C++ expresiones regulares con Boost Regex

He leído mucha documentación sobre regex, pero parece que no puedo entender cómo hacer esta simple función.

Creo que puedo usar esta expresión Perl para encontrar cualquier dirección IP:

re("\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"); 

pero todavía estoy perplejo sobre cómo hacer el resto.

+0

¿Has probado el tutorial y la documentación de Boost Regex? ¿Tienes algún código para compartir con nosotros? –

+0

¿qué estás tratando de hacer coincidir exactamente con esa expresión regular? Primero intente hacer coincidir una sola dirección IP – snoofkin

+1

Eche un vistazo al excelente tutorial de John D Cook [Cómo comenzar con las expresiones regulares de C++ TR1] (http://www.johndcook.com/cpp_regex.html). Está diseñado para aquellos que ya entienden el RegEx pero no saben cómo hacer cosas en C++. –

Respuesta

12

Quizás esté buscando algo como esto. Utiliza regex_iterator para obtener todas las coincidencias del patrón actual. Ver reference.

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

int main() 
{ 
    std::string text(" 192.168.0.1 abc 10.0.0.255 10.5.1 1.2.3.4a 5.4.3.2 "); 
    const char* pattern = 
     "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
     "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
     "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
     "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"; 
    boost::regex ip_regex(pattern); 

    boost::sregex_iterator it(text.begin(), text.end(), ip_regex); 
    boost::sregex_iterator end; 
    for (; it != end; ++it) { 
     std::cout << it->str() << "\n"; 
     // v.push_back(it->str()); or something similar  
    } 
} 

Salida:

192.168.0.1 
10.0.0.255 
5.4.3.2 

Nota al margen: es probable que significó \\b en lugar de \b; Dudo que hayas esperado para que coincida con el carácter de retroceso.

+0

El "extremo" del iterador no se ha inicializado. ¿Eso esta bien? – truthseeker

+0

@truthseeker: se inicializa por constructor predeterminado. – Vitus

+1

El final se construye por defecto, pero este algoritmo tiene errores (adyacencia, justificación a la izquierda, justificación a la derecha) y la expresión regular es incorrecta (y lenta de otro modo). – FauChristian

-1

La solución ofrecida es bastante buena, gracias por ello. Aunque encontré un pequeño error en el patrón en sí.

Por ejemplo, algo así como 49.000.00.01 se tomaría como una dirección IPv4 válida y, desde mi entender, no debería ser (me acaba de ocurrir durante algún proceso de volcado).

me sugieren para mejorar el golpeteo en:

"\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)" 
"\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)" 
"\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)" 
"\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\\b"; 

Esto sólo 0.0.0.0 como el de todo ceros-in, que supongo que es correcta y debe permitir que eliminará todas .00. .000. etc.

0
#include <string> 
#include <list> 
#include <boost/regex.hpp> 
typedef std::string::const_iterator ConstIt; 

int main() 
{ 
    // input text, expected result, & proper address pattern 
    const std::string sInput 
    (
      "192.168.0.1 10.0.0.255 abc 10.5.1.00" 
      " 1.2.3.4a 168.72.0 0.0.0.0 5.4.3.2" 
    ); 
    const std::string asExpected[] = 
    { 
     "192.168.0.1", 
     "10.0.0.255", 
     "0.0.0.0", 
     "5.4.3.2" 
    }; 
    boost::regex regexIPs 
    (
     "(^|[ \t])(" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])[.]" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])[.]" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])[.]" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])" 
     ")($|[ \t])" 
    ); 

    // parse, check results, and return error count 
    boost::smatch what; 
    std::list<std::string> ns; 
    ConstIt end = sInput.end(); 
    for (ConstIt begin = sInput.begin(); 
       boost::regex_search(begin, end, what, regexIPs); 
       begin = what[0].second) 
    { 
     ns.push_back(std::string(what[2].first, what[2].second)); 
    } 

    // check results and return number of errors (zero) 
    int iErrors = 0; 
    int i = 0; 
    for (std::string & s : ns) 
     if (s != asExpected[i ++]) 
      ++ iErrors; 
    return iErrors; 
} 
Cuestiones relacionadas