Регулярные выражения C++ с регулярным выражением Boost

Я пытаюсь взять строку в C++ и найти все IP-адреса, содержащиеся внутри, и поместить их в новую векторную строку.

Я прочитал много документации по регулярному выражению, но я просто не могу понять, как сделать эту простую функцию.

Я считаю, что могу использовать это выражение Perl для поиска любого 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");

но я все еще в тупике, как сделать все остальное.

3 ответов


возможно, вы ищете что-то вроде этого. Он использует regex_iterator чтобы получить все совпадения текущего шаблона. См.ссылка.

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

выход:

192.168.0.1
10.0.0.255
5.4.3.2

Примечание: Вы, вероятно, имели в виду \b вместо \b; Я сомневаюсь, что вы watnted, чтобы соответствовать символ возврата.


предлагаемое решение довольно хорошее, спасибо за него. Хотя я обнаружил небольшую ошибку в самой схеме.

например, что-то вроде 49.000.00.01 будет принято в качестве действительного адреса IPv4, и, насколько я понимаю, этого не должно быть (просто случилось со мной во время обработки дампа).

Я предлагаю улучшить скороговорку в:

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

Это должно позволить только 0.0.0.0 как all-zero-in, что, я полагаю, правильно, и это устранит все .00. .000. так далее.


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