8
votes

Expressions régulières C ++ avec Boost Regex

J'essaie de prendre une chaîne en C ++ et de trouver toutes les adresses IP contenues à l'intérieur et mettez-les dans une nouvelle chaîne de vecteur.

J'ai lu beaucoup de documentation sur regex, mais je n'arrive pas à comprendre comment faire cette fonction simple. P>

Je pense que je peux utiliser cette expression Perl pour trouver n'importe quelle adresse IP : P>

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");


4 commentaires

Avez-vous essayé le didacticiel et la documentation de Boost Regex? Vous avez du code jusqu'à présent pour partager avec nous?


Qu'est-ce que vous essayez exactement de faire correspondre avec cette regex? D'abord essayer de faire correspondre une seule adresse IP


John D Cook's excellent tutoriel Mise en route avec C ++ TR1 Expressions régulières . Il est conçu pour ceux qui comprennent déjà la regex mais ne peuvent pas comprendre comment le faire faire des choses en C ++.


QU'EST-THE REALE BUGES: Il permet 00 et cela ne fonctionne pas avec les adresses IP justifiées par gauche ou droite. Il n'est également pas syntaxiquement factorisé pour une vitesse maximale. Le bon est à stackoverflow .com / questions / 5804453 / ... .


3 Réponses :


15
votes

Peut-être que vous cherchez quelque chose comme ça. Il utilise regex_iterator code> pour obtenir toutes les correspondances du motif actuel. Voir Référence .

192.168.0.1
10.0.0.255
5.4.3.2


3 commentaires

Itérateur "End" n'est pas initialisé. Est-ce que ça va?


@Truthseeker: il est initialisé par constructeur par défaut.


La fin est construite par défaut, mais cet algorithme a des bugs (adjacence. Justification de gauche, justification droite) et la regex est fausse (et sinon lent).



-1
votes

La solution proposée est assez bonne, merci pour cela. Bien que j'ai trouvé une légère erreur dans le motif lui-même.

Par exemple, quelque chose comme 49.000.00.01 serait considéré comme une adresse IPv4 valide et de ma compréhension, cela ne devrait pas être (juste m'est arrivé pendant un traitement de vidage) .

Je suggère d'améliorer le type dans: xxx

ceci ne devrait autoriser que 0.0.0.0 comme le tout zéro-in, que je suppose être correct et cela éliminera tout .00. .000. c.


0 commentaires

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

0 commentaires