2014-11-02 15 views
19

Sotto il programma è stato scritto per recuperare le informazioni "Giorno" utilizzando il C++ 11 std::regex_match & std::regex_search. Tuttavia, l'utilizzo del primo metodo restituisce false e il secondo metodo restituisce true (previsto). Ho letto la documentazione e la domanda SO già esistente relativa a questo, ma non capisco la differenza tra questi due metodi e quando dovremmo usare uno di essi? Possono essere usati entrambi in modo intercambiabile per qualsiasi problema comune?Differenza tra 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"; 
    } 
} 

uscita

Did Not Found 

Found 

25 

Perché primo metodo regex ritorna false in questo caso ?. Il regex sembra essere corretto, quindi idealmente entrambi avrebbero dovuto essere restituiti true. Ho eseguito il programma di cui sopra modificando loe trovato che restituisce ancora false.

Qualcuno potrebbe spiegare l'esempio precedente e, in generale, utilizzare casi di questi metodi?

risposta

18

regex_match restituisce solo true quando l'intera sequenza di input è stato abbinato, mentre regex_search avrà successo, anche se solo un sotto-sequenza corrisponde al regex.

Citando N3337,

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

Effetti: Determina se v'è una corrispondenza tra l'espressione regolare e e tutta la sequenza di caratteri [first,last). ... Restituisce true se esiste una corrispondenza di questo tipo, false in caso contrario.

La descrizione precedente riguarda il sovraccarico regex_match che richiede una coppia di iteratori nella sequenza da abbinare. I sovraccarichi rimanenti sono definiti in termini di questo sovraccarico.

La corrispondente regex_search sovraccarico è descritta come

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

Effetti: Determina se c'è qualche sub sequenza entro [first,last) che corrisponde all'espressione regolare e. ... Restituisce true se esiste una sequenza di questo tipo, false in caso contrario.


Nel tuo esempio, se si modifica il regex-r{R"(.*?\s\d{2}\s.*)"}; sia regex_match e regex_search riuscirà (ma il risultato della partita non è solo il giorno, ma l'intera stringa data).

Live demo di una versione modificata dell'esempio in cui il giorno viene catturato e visualizzato da entrambi regex_match e regex_search.

+0

Grazie per la spiegazione. Potresti spiegare perché abbiamo dovuto cambiare dalla partita [0] per abbinare [1] per ottenere il risultato esatto in entrambi i casi ?. Voglio dire, parla di std :: smatch usa comprensione. –

+1

@MantoshKumar Ho aggiunto le parentesi attorno al campo della data '(\ d {2})' per creare un gruppo di cattura. Dalla 'match_results' [documentazione] (http://en.cppreference.com/w/cpp/regex/match_results/operator_at),' match [0] 'restituisce sempre l'intera espressione abbinata, mentre' match [1] ' restituisce la prima sotto-partita e così via. In questo caso, abbiamo avuto solo un gruppo di acquisizione, per il giorno, e quindi è archiviato nella prima sotto-partita. – Praetorian

12

È molto semplice. regex_search esamina la stringa per trovare se una parte della stringa corrisponde alla regex. regex_match controlla se l'intera stringa corrisponde alla regex. Come semplice esempio, data la seguente stringa:

"one two three four" 

Se uso regex_search su tale stringa con l'espressione "three", avrà successo, perché "three" può essere trovato in "one two three four"

Tuttavia, se uso regex_match invece, fallirà, perché "three" non è l'intera stringa, ma solo una parte di essa.

Problemi correlati