2014-11-02 26 views
19

Unterhalb des Programms wurde geschrieben, um die "Day" Informationen mit dem C++ 11 std::regex_match & std::regex_search zu holen. Die erste Methode gibt jedoch false zurück und die zweite Methode gibt true (erwartet) zurück. Ich habe die Dokumentation und die bereits bestehende SO-Frage gelesen, aber ich verstehe den Unterschied zwischen diesen beiden Methoden nicht und wann sollten wir beide verwenden? Können beide für ein beliebiges Problem austauschbar verwendet werden?Unterschied zwischen std :: regex_match & std :: regex_search?

Difference between regex_match and 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"; 
    } 
} 

Ausgabe

Did Not Found 

Found 

25 

Warum erste regex Methode gibt false in diesem Fall ?. Die regex scheint korrekt zu sein, also sollten beide idealerweise true zurückgegeben werden. Ich lief das obige Programm durch die std::regex_match(input,match,r)-std::regex_match(input,r) verändert und festgestellt, dass es immer noch gibt false.

Könnte jemand das obige Beispiel erklären und im allgemeinen Anwendungsfall dieser Methoden?

Antwort

18

regex_match liefert nur true, wenn die gesamte Eingangssequenz abgestimmt wurde, während regex_search gelingen wird, auch wenn nur eine Teilsequenz der regex übereinstimmt.

von N3337,

Zitiert

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

Effekte: Legt fest, ob es eine Übereinstimmung e zwischen dem regulären Ausdruck ist und die gesamte Zeichenfolge [first,last). ... Gibt true zurück, wenn eine solche Übereinstimmung existiert, andernfalls false.

Die obige Beschreibung ist für die regex_match Überlastung, das ein Paar von Iteratoren zur Sequenz angepasst zu werden braucht. Die verbleibenden Überlasten sind in Bezug auf diese Überlast definiert.

Die entsprechende regex_search Überlastung wird beschrieben als

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

Effekte: bestimmt, ob es einige sub- Sequenz innerhalb [first,last), die den regulären Ausdruck e entspricht. ... Gibt true zurück, wenn eine solche Sequenz existiert, andernfalls false.


In Ihrem Beispiel, wenn Sie die regex-r{R"(.*?\s\d{2}\s.*)"}; beide regex_match und regex_search ändern wird erfolgreich sein (aber das Spiel Ergebnis ist nicht nur der Tag, sondern das gesamte Datum string).

Live demo einer modifizierten Version Ihres Beispiels, in der der Tag sowohl von regex_match als auch regex_search erfasst und angezeigt wird.

+0

Danke für die Erklärung. Könnten Sie bitte erklären, warum wir von Match [0] auf Match [1] umstellen mussten, um das genaue Ergebnis in beiden Fällen zu erhalten? Ich meine es geht um std :: smatch nutzt verständnis. –

+1

@MantoshKumar Ich habe Klammern um das Datumsfeld '(\ d {2})' eingefügt, um eine Erfassungsgruppe zu erstellen. Aus den 'match_results' [Dokumentation] (http://en.cppreference.com/w/cpp/regex/match_results/operator_at) gibt' match [0] 'immer den gesamten übereinstimmenden Ausdruck zurück, während' match [1] ' Liefert das erste Untermatch und so weiter. In diesem Fall hatten wir nur eine Erfassungsgruppe für den Tag und dies wird im ersten Untermatch gespeichert. – Praetorian

12

Es ist sehr einfach. regex_search durchsucht die Zeichenfolge, um festzustellen, ob ein Teil der Zeichenfolge mit der Regex übereinstimmt. regex_match überprüft, ob die ganze Zeichenfolge eine Übereinstimmung für die Regex ist. Als einfaches Beispiel, die folgende Zeichenfolge angegeben:

"one two three four" 

Wenn ich regex_search auf dieser Zeichenfolge mit dem Ausdruck verwende "three", wird es gelingen, weil "three"

jedoch in "one two three four" gefunden werden kann, wenn ich regex_match verwenden stattdessen wird es fehlschlagen, weil nicht die ganze Zeichenfolge ist, sondern nur ein Teil davon.

Verwandte Themen