Как мне просмотреть результаты из std :: regex_search? - PullRequest
10 голосов
/ 04 сентября 2011

После вызова std::regex_search я могу получить только первый строковый результат из std::smatch по какой-то причине:

Expression.assign("rel=\"nofollow\">(.*?)</a>");
if (std::regex_search(Tables, Match, Expression))
{
    for (std::size_t i = 1; i < Match.size(); ++i)
        std::cout << Match[i].str() << std::endl;
}

Поэтому я попытался сделать это по-другому - с помощью итератора:

const std::sregex_token_iterator End;
Expression.assign("rel=\"nofollow\">(.*?)</a>");
for (std::sregex_token_iterator i(Tables.begin(), Tables.end(), Expression); i != End; ++i)
{
    std::cout << *i << std::endl;
}

Это проходит каждый матч, но также дает мне всю совпадающую строку, а не только захват, который я получил после.Разумеется, это должен быть другой способ, чем сделать еще один std::regex_search для элемента итератора в цикле?

Заранее спасибо.

Ответы [ 2 ]

9 голосов
/ 05 сентября 2011

regex_token_iterator принимает необязательный четвертый аргумент, определяющий, какой субматч возвращается для каждой итерации. Значение этого аргумента по умолчанию равно 0, что в случае регулярных выражений C ++ (и многих других) означает «полное совпадение». Если вы хотите получить первый захваченный субматч, просто передайте 1 конструктору:

const std::sregex_iterator End;
Expression.assign("rel=\"nofollow\">(.*?)</a>");
for (std::sregex_token_iterator i(Tables.begin(), Tables.end(), Expression, 1); i != End; ++i)
{
    std::cout << *i << std::endl; // *i only yields the captured part
}
5 голосов
/ 05 сентября 2011

std::regex_search ищет регулярное выражение только один раз. Он не возвращает список совпадений, но список выражений, которые не совпадают (в скобках). Вот почему вы получаете только один Match[1] текст внутри тега ссылки.

Что касается второго кода, он на самом деле возвращает вам все совпадения, но он снова возвращает вам match_results объект, поэтому вы должны использовать оператор []:

const std::sregex_iterator End;
Expression.assign("rel=\"nofollow\">(.*?)</a>");
for (std::sregex_iterator i(Tables.begin(), Tables.end(), Expression); i != End; ++i)
{
    std::cout << (*i)[1] << std::endl; // first submatch, same as above.
}
...