Подтвердить что ты не робот

Разница между std:: regex_match и std:: regex_search?

Ниже была записана программа для получения информации "День" с использованием С++ 11 std:: regex_match и std:: regex_search. Однако использование первого метода возвращает false, а второй метод возвращает true (ожидается). Я прочитал документацию и уже существующий вопрос SO, связанный с этим, но я не понимаю разницу между этими двумя методами и когда мы должны использовать любой из них? Могут ли они использоваться как взаимозаменяемые для любой общей проблемы?

Разница между regex_match и regex_search?

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

int main()
{
    std::string input{ "Mon Nov 25 20:54:36 2013" };
    //Day:: Exactly Two Number surrounded by spaces in both side
    std::regex  r{R"(\s\d{2}\s)"};
    //std::regex  r{"\\s\\d{2}\\s"};
    std::smatch match;

if (std::regex_match(input,match,r)) {
        std::cout << "Found" << "\n";
    } else {
        std::cout << "Did Not Found" << "\n";
    }

    if (std::regex_search(input, match,r)) {
        std::cout << "Found" << "\n";
        if (match.ready()){
            std::string out = match[0];
            std::cout << out << "\n";
        }
    }
    else {
        std::cout << "Did Not Found" << "\n";
    }
}

Выход

Did Not Found

Found

 25 

Почему первый метод regex возвращает false в этом случае?. regex кажется правильным, поэтому в идеале оба должны были быть возвращены true. Я запустил вышеуказанную программу, изменив std::regex_match(input,match,r) на std::regex_match(input,r) и обнаружив, что он все еще возвращает false.

Может ли кто-нибудь объяснить приведенный выше пример и, в общем, использовать случаи этих методов?

4b9b3361

Ответ 1

regex_match возвращает только true, когда вся входная последовательность согласована, а regex_search будет успешной, даже если только подпоследовательность соответствует regex.

Цитата из N3337,

§28.11.2/2 regex_match [re.alg.match]

Эффекты: Определяет, существует ли соответствие между регулярным выражением e и всей последовательности символов [first,last). ... Возвращает true, если такое совпадение существует, false в противном случае.

Вышеприведенное описание относится к перегрузке regex_match, которая берет пару итераторов в последовательность, подлежащую согласованию. Оставшиеся перегрузки определены в терминах этой перегрузки.

Соответствующая перегрузка regex_search описывается как

§28.11.3/2 regex_search [re.alg.search]

Эффекты: Определяет, существует ли какая-либо подпоследовательность внутри [first,last), которая соответствует регулярному выражению e. ... Возвращает true, если такая последовательность существует, false в противном случае.


В вашем примере, если вы измените regex на r{R"(.*?\s\d{2}\s.*)"};, оба regex_match и regex_search будут успешными (но результат совпадения - это не только день, но и вся строка даты).

Живая демонстрация измененной версии вашего примера, где день записывается и отображается как regex_match, так и regex_search.

Ответ 2

Это очень просто. regex_search просматривает строку, чтобы найти, соответствует ли какая-либо часть строки регулярному выражению. regex_match проверяет, соответствует ли целая строка регулярному выражению. В качестве простого примера можно привести следующую строку:

"one two three four"

Если я использую regex_search в этой строке с выражением "three", это будет успешным, потому что "three" можно найти в "one two three four"

Однако, если я использую regex_match вместо этого, он потерпит неудачу, потому что "three" - это не вся строка, а только ее часть.