Регулярные выражения C ++ с регулярным выражением Boost - PullRequest
8 голосов
/ 27 апреля 2011

Я пытаюсь взять строку в 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 ]

14 голосов
/ 27 апреля 2011

Возможно, вы ищете что-то подобное.Он использует 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;Я сомневаюсь, что вы смотрели, чтобы соответствовать символу возврата.

0 голосов
/ 21 марта 2017
#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 голосов
/ 20 октября 2013

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

Например, что-то вроде 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 в качестве нуля, что, как я полагаю, является правильным, и этоустранит все .00.0,000.и т.д.

...