2016-12-20 1 views
0

Mit this regex möchte ich Zeit mit oder ohne ein Millisekunden (ms) Feld übereinstimmen. Der Vollständigkeit halber schreibe ich die Regex hier (ich die Anker in regex101 entfernt mehrzeiligen zu aktivieren):C++ 11: Sicheres Üben mit Regex von zwei möglichen Übereinstimmungen

^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:|(?:\.)([0-9]{1,6}))$ 

ich irgendwie nicht das C++ Verhalten verstehen. Jetzt sehen Sie in Regex101, die Anzahl der Capture-Gruppen hängt von der Zeichenfolge ab. Wenn es keine ms gibt, ist es 3 + 1 (da C++ die Übereinstimmung [0] für das übereinstimmende Muster verwendet), und wenn es ms gibt, dann ist es 4 + 1. Aber dann in diesem Beispiel:

std::regex timeRegex = std::regex(R"(^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:|(?:\.)([0-9]{1,6}))$)"); 
std::smatch m; 
std::string strT = std::string("12:00:09"); 
bool timeMatch = std::regex_match(strT, m, timeRegex); 
std::cout<<m.size()<<std::endl; 
if(timeMatch) 
{ 
    std::cout<<m[0]<<std::endl; 
    std::cout<<m[1]<<std::endl; 
    std::cout<<m[2]<<std::endl; 
    std::cout<<m[3]<<std::endl; 
    std::cout<<m[4]<<std::endl; 
} 

Wir sehen, dass m.size() ist immer 5, ob es oder nicht ms Feld! m[4] ist eine leere Zeichenfolge, wenn kein MS-Feld vorhanden ist. Ist dieses Verhalten der Standard in Regex von C++? Oder sollte ich versuchen (oder irgendeine andere Sicherheitsmaßnahme), wenn Zweifel an der Größe sind? Ich meine ... selbst die Größe ist hier ein wenig irreführend!

+0

Sind Sie fragen, warum gibt es fünf Gruppen alles in allem? Weil Sie eine ganze Übereinstimmung + 4 Erfassungsgruppen im Muster definiert haben. Ob die Gruppe übereinstimmt oder nicht, ist gemäß ECMAScript scpes nicht wichtig, leere Gruppen werden immer mit einer leeren Zeichenfolge vorbelegt. –

+0

@ WiktorStribiżew Bitte überprüfen Sie den regex101 Link, den ich zur Verfügung gestellt habe. Falls es kein ms-Feld gibt, sollte es nur 3 + 1, nicht 4 + 1 sein. –

+0

Es ist mir egal, und Sie und alle Benutzer sollten sich nicht darum kümmern, was regex101 zeigt oder nicht, es hat seine eigenen Bugs. Was wichtig ist, ist das, was Sie im Code haben. Du hast 4 Capturing Groups definiert - es gibt 4 Slots für jede + 1 für das ganze Match bei Index 0. –

Antwort

3

m.size() wird immer die Anzahl der markierten Unterausdrücke in Ihrem Ausdruck plus 1 (für den gesamten Ausdruck) sein.

In Ihrem Code haben Sie 4 markierte Unterausdrücke, ob diese übereinstimmen oder nicht hat keinen Einfluss auf die Größe von m.

Wenn Sie wollen jetzt, wenn es Millisekunden sind, können Sie überprüfen:

m[4].matched 
0

std::smatch (a.k.a. std::match_results<std::string::const_iterator>) ist im Grunde ein Container, der Elemente des Typs std::sub_match enthält. Das erste Element enthält die Übereinstimmungsergebnisse für Ihren vollständigen regulären Ausdrucksausdruck, und die folgenden enthalten Übereinstimmungen für jeden Unterausdruck. Da Sie 4 Unterausdrücke haben, wenn Sie Ihr Muster haben, erhalten Sie 5 Ergebnisse (4 + vollständige Übereinstimmung).

2
m.size();// Returns the number of match results. 
     // a string is allocated for each 'Capture Group' 
     // and filled with the match substring. 

Da smatch ein match_results ist

(siehe) http://www.cplusplus.com/reference/regex/match_results/

Größe gibt die Anzahl von Übereinstimmungen, die ALLOCATED zugeordnet wurden, basierend auf der Anzahl von Erfassungsgruppen, die in Ihrer Regex enthalten sind.

Capture-Gruppen:

Klammerung Gruppe zwischen ihnen die Regex. Sie erfassen den von der Regex übereinstimmenden Text in einer nummerierten Gruppe, die mit einer nummerierten Rückwärtsreferenz wiederverwendet werden kann. Mit ihnen können Sie Regex-Operatoren auf den gesamten gruppierten Regex anwenden.

http://www.regular-expressions.info/refcapture.html

Also das ist, warum Ihre Größe als 5 egal zugeteilt werden wird, was Sie mit regex_match Füllung Ende(). Wie andere notex haben, ist der fünfte das vollständige Spiel.

Siehe: What does std::match_results::size return?

+0

Dies hilft. Ich habe es getan. Vielen Dank :) –

Verwandte Themen