web-dev-qa-db-fra.com

Différence entre std :: regex_match et std :: regex_search?

Le programme ci-dessous a été écrit pour récupérer les informations "Jour" en utilisant le C++ 11 std :: regex_match & std :: regex_search . Cependant, l'utilisation de la première méthode renvoie false et la deuxième méthode renvoie true (attendu). J'ai lu la documentation et la question SO déjà existante liée à cela, mais je ne comprends pas la différence entre ces deux méthodes et quand nous devrions utiliser l'une ou l'autre? Peut-elle être utilisée de manière interchangeable pour Problème commun?

Différence entre regex_match et 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";
    }
}

Production

Did Not Found

Found

 25 

Pourquoi la première méthode d'expression régulière renvoie false dans ce cas?. Le regex semble être correct, donc idéalement les deux auraient dû être retournés true. J'ai exécuté le programme ci-dessus en changeant la std::regex_match(input,match,r) en std::regex_match(input,r) et j'ai trouvé qu'il renvoie toujours false.

Quelqu'un pourrait-il expliquer l'exemple ci-dessus et, en général, utiliser les cas de ces méthodes?

30
Mantosh Kumar

regex_match Ne renvoie true que lorsque la séquence d'entrée entière a été mise en correspondance, tandis que regex_search Réussira même si seule une sous-séquence correspond à regex.

Citant N3337,

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

Effets: Détermine s'il existe une correspondance entre l'expression régulière e et toute la séquence de caractères [first,last). ... Renvoie true si une telle correspondance existe, false sinon.

La description ci-dessus concerne la surcharge regex_match Qui amène une paire d'itérateurs à la séquence à mettre en correspondance. Les surcharges restantes sont définies en fonction de cette surcharge.

La surcharge regex_search Correspondante est décrite comme

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

Effets: Détermine s'il y a une sous-séquence dans [first,last) qui correspond à l'expression régulière e. ... Renvoie true si une telle séquence existe, false sinon.


Dans votre exemple, si vous modifiez la regex en r{R"(.*?\s\d{2}\s.*)"}; les deux regex_match Et regex_search Réussiront (mais le résultat de la correspondance n'est pas seulement le jour, mais toute la chaîne de date).

Démo en direct d'une version modifiée de votre exemple où le jour est capturé et affiché par regex_match Et regex_search.

26
Praetorian

C'est très simple. regex_search examine la chaîne pour trouver si une partie de la chaîne correspond à l'expression régulière. regex_match vérifie si la chaîne entière correspond au regex. À titre d'exemple simple, étant donné la chaîne suivante:

"one two three four"

Si j'utilise regex_search sur cette chaîne avec l'expression "three", il réussira, car "three" peuvent être trouvés dans "one two three four"

Cependant, si j'utilise regex_match à la place, il échouera, car "three" n'est pas la chaîne entière, mais seulement une partie.

15
Benjamin Lindley