Попытка извлечь часть кода html с помощью регулярного выражения - PullRequest
1 голос
/ 06 августа 2020

У меня есть код html, например

<tr class="class1">
    <td class="class2">
        <a href="some_address"></a>
        <div id="id1">
            <span class="class3"></span>
        </div>
        <span>Just a text</span>
    </td>
</tr>

Мне нужно извлечь фрагмент кода между тегами <tr class="class1"> и </tr>. Я использую это регулярное выражение https://regex101.com/r/Z0Pmgg/1. И вроде работает. Но когда я пытаюсь использовать это выражение в C ++ STL, оно вообще не работает: (

#include <string>
#include <regex>
#include <iostream>

int main()
{
    std::string str = "<tr class=\"class1\">\n"
                          "<td class=\"class2\">\n"
                              "<a href=\"some_address\"></a>\n"
                              "<div id=\"id1\">\n"
                                  "<span class=\"class3\"></span>\n"
                              "</div>\n"
                              "<span>Just a text</span>\n"
                          "</td>\n"
                      "</tr>\n";
    std::cmatch result;
    std::regex regular("(<tr class=\"class1\">)"
                       "([\s\S]*?)"
                       "(<\/tr>)");
    if (std::regex_match(str.c_str(), result, regular))
        std::cout << "Success\n" << result[2] << std::endl;
    return 0;
}

Что я делаю не так? Я также пытался использовать regex_search () вместо

1 Ответ

1 голос
/ 07 августа 2020

Вам нужно избежать \ и принять во внимание окончательный \n, или еще лучше, используйте regex_iterator вместо regex_match.

Следующее работает для меня в G CC 8, Clang 8 и MSV C 14:

#include <string>
#include <regex>
#include <iostream>

int main()
{
    std::string str = "<tr class=\"class1\">\n"
        "<td class=\"class2\">\n"
        "<a href=\"some_address\"></a>\n"
        "<div id=\"id1\">\n"
        "<span class=\"class3\"></span>\n"
        "</div>\n"
        "<span>Just a text</span>\n"
        "</td>\n"
        "</tr>\n";
    std::regex re("(<tr class=\"class1\">\\s*)"
        "([\\s\\S]*?)"
        "(\\s*</tr>\\s*)");

    for (std::sregex_iterator it{ str.begin(), str.end(), re }, end{}; it != end; it++) {
        std::smatch result = *it;
        std::cout << "Found:\n\n" << result[2] << "\n";
    }
}

Вывод:

Found:

<td class="class2">
<a href="some_address"></a>
<div id="id1">
<span class="class3"></span>
</div>
<span>Just a text</span>
</td>

Примечание: в некоторых старых реализациях libstdc ++ и libc ++ возникли трудности с пониманием символов классы внутри диапазона регулярных выражений [...]. В этом случае попробуйте заменить [\\s\\S] на (?:\\s|\\S) (или еще лучше, обновите libstdc ++ до 6-4.9.1 или новее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...