std::regex



  • Huch?



  • Also es ist natürlich auch nervig, sich dort wiederholen zu müssen, da hast Du natürlich Recht, aber mit meiner Frage wollte ich auf etwas anderes abzielen.
    Wenn ich das besagte Muster per regex_match auf den String "1;2" anwende, bekomme ich als Resultat "1;2", "1", ";2" und "2". Ich würde das Muster gern so hinbekommen, dass ich die Resultate "1" und "2" erhalte.



  • ich meinte ungefähr so:

    #define MYSUBEXPR "\\s*(\\d{1,2})\\s*"
      const std::regex pattern(MYSUBEXPR "(;" MYSUBEXPR ")*");
    


  • dd, du bis ganz am falschen thema. kann er klammen zum Binden benutzen, ohne daß die im Ergebnis Strings erzeugen?



  • Das geht mit einer Non-Capturing Group: "(?:expr)".



  • Ich habe es durch die Channel9-Präsentation von STL und dann über non capturing groups gefunden. (?: ist die Einleitung einer non capturing group!

    Edit: Danke Michael E., ich kam leider zu spät!



  • Okay, das funktioniert zwar vom matching-Standpunkt aus, aber so kann ich nicht die Zahlen aus einem String mit beliebiger anzahl von auftretenden Gruppen rausparsen. Am Ende steht halt für jede Gruppe genau ein Ergebnis da und das ist natürlich das letzte: "1;2;3" => "1" und "3". Kann ich das erfolgreiche Auftreten/Parsen einer Gruppe irgendwie dazu veranlassen, mich mit dem Ergebnis zu benachrichtigen, sodass ich selber eine Liste anfertigen kann?

    Edit: Ich könnte natürlich mit "\\s*;\\s*" tokenizen und die Tokens hinterher nochmal durch eine andere regex laufen lassen, aber es muss doch einen Dreizeiler geben für das, was ich vorhabe O.O

    Edit #2:

    So sieht das jetzt aus, wobei ich den Eindruck bekomme, dass ich gleich mit 2 Kanonen auf einen Spatzen schieße...

    const std::wregex tokenpattern( L"[^;]" );
    const std::wregex numberpattern( L"\\s*(\\d{1,2})\\s*" );
    std::match_results<std::wstring::const_iterator> result;
    std::regex_token_iterator<std::wstring::const_iterator> end;
    std::regex_token_iterator<std::wstring::const_iterator> it( selection.begin(), selection.end(), tokenpattern );
    
    for( unsigned int i=0; it != end; ++it, ++i ) {
    	std::wstring str = it->str();
    	std::regex_match( str, result, numberpattern );
            // ...
    }
    


  • Langsam wird's mir unklar.

    Was soll bei "2;3;5;7;11;13;17;19" herauskommen?
    Und sind die Formatbeschränkungen (abgesehen von whitespaces nur, daß mindestens eine Zahl in der Liste ist, jede Zahl eine oder zwei Ziffern hat und zwischen zei Zahlen stets ein Semikolon stehen muss?



  • Ja genau Volkard! (Siehe den Edit meines vorigen Posts, wie ich das jetzt hingefummelt habe)

    "2", "3", "5", "7", "11", "13", "17", "19" hätte ich gerne. Ich brauche keine komplette Liste, mir würde auch reichen, die in dieser Reihenfolge aufgezählt zu bekommen.



  • ich hatte bisher mit QRegExp gearbeitet, die verhalten sich etwas anders. mit std::regex kann man das etwa so machen:

    #include <string>
    #include <iostream>
    #include <regex>
    
    int main ()
      {
      std::regex Pattern("(\\d+);");
      std::smatch Match;
      std::string Data = "12;34;56;78;90;";
      std::string::const_iterator Begin = Data.begin();
      std::string::const_iterator End = Data.end();
    
      while (std::regex_search(Begin, End, Match, Pattern,
             std::regex_constants::match_continuous))
        {
        Begin = Match[0].second;
        std::cout << Match[1] << std::endl;
        }
      }
    

Anmelden zum Antworten