C++ Regular Expressions with Boost Regex

前端 未结 3 1299
忘掉有多难
忘掉有多难 2020-12-05 12:36

I am trying to take a string in C++ and find all IP addresses contained inside, and put them into a new vector string.

I\'ve read a lot of documentation on regex, b

相关标签:
3条回答
  • 2020-12-05 12:51

    Perhaps you're looking for something like this. It uses regex_iterator to get all matches of the current pattern. See 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     
        }
    }
    

    Output:

    192.168.0.1
    10.0.0.255
    5.4.3.2
    

    Side note: you probably meant \\b instead of \b; I doubt you watnted to match backspace character.

    0 讨论(0)
  • 2020-12-05 13:01

    The offered solution is quite good, thanks for it. Though I found a slight mistake in the pattern itself.

    For example, something like 49.000.00.01 would be taken as a valid IPv4 address and from my understanding, it shouldn't be (just happened to me during some dump processing).

    I suggest to improve the patter into:

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

    This should allow only 0.0.0.0 as the all-zero-in, which I suppose to be correct and it will eliminate all .00. .000. etc.

    0 讨论(0)
  • 2020-12-05 13:05
    #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 讨论(0)
提交回复
热议问题