C++: Reguläre Audrücke verstehen und umsetzen



  • @Swordfish, heißt das, ich kann die egrep-Syntax ganz einfach auch auf Regex anwenden? Beides ist von der Syntax identisch? Oder könnte es Probleme geben?



  • Es gibt nicht "die" Regex-Syntax, es gibt verschiedene Dialekte. Was egrep verwendet weiss ich nicht. Kannst du aber sicher irgendwo nachlesen. Die Dialekte sind sich aber sehr ähnlich, und gerade einfache Dinge sind quasi überall gleich. Also allgemein... ja, sollte im grossen und ganzen schon hinhauen.

    Davon abgesehen: egrep ist ein Command-Line Tool. Und so ein Command-Line Tool bekommt nicht in jedem Fall 1:1 das gefüttert was du in der Shell eintippst. Da spielt noch das Escaping der Shell mit rein.

    Also angenommen du willst mit ner Regex nach einem Stern suchen. Dann muss du den für die Regex erstmal escapen, also \*. Wenn deine Shell jetzt ebenso \ als Escape-Character verwendet, dann musst du das nochmal escapen: \\*. Und damit die Shell weiss dass sie nicht globben soll, solltest du das ganze noch quoten: "\\*"

    D.h. "\\*" als Argument für egrep entspricht der Regex \*.



  • @hustbaer, danke für die Erläuterung! Kriegst dafür ein Salbei-Bonbon 😛 🙂

    Habe auch schon das Buch "Reguläre Ausdrücke" bekommen. Echt super erklärt!



  • @wob, das mit dem Doppelbackslash funktioniert bei mir nicht. Es wird dann der gesamte String ausgegeben.

    Und wie bekomme ich es hin, mehrere Funde auszugeben? Wenn in dem String z.B. zwei mal der selbe Text vorkommt, nur mit zwei unterschiedlichen Alter? Ich habe es bereits mit

    cm[1].str()  //erster Fund
    cm[2].str()  //zweiter Fund
    

    versucht, aber die Anweisung cm[2].str() gibt nur einen leeren String zurück.



  • @DerDaVinciKot Zeig mal ein minimales aber vollständiges Beispiel wo das Problem auftritt. Es wurde in diesem Thread einiges geschrieben/empfholen und zumindest ich bin mir jetzt nicht sicher was du davon wie umgesetzt hast/wie dein Code jetzt aussieht.



  • Das tu ich doch gern!

    std::regex re(R"(Peter ist (\d+) Jahre alt.*)");
        std::cmatch cm;
        std::regex_match("Peter ist 70 Jahre alt und hat bereits Probleme sich die Schuhe anzuziehen.Peter ist 80 Jahre alt und hat bereits Probleme sich die Schuhe anzuziehen.", cm, re);
    
        qDebug() << QString::fromStdString(cm[1].str());               
        qDebug() << QString::fromStdString(cm[2].str());
    

    Ausgabe:
    "70"
    ""
    Wie bekomme ich es hin, beide Altersangaben (70 und 80) auszugeben?



  • #include <string>
    #include <regex>
    
    int main()
    {
        std::regex re(R"(Peter ist (\d+) Jahre alt)");
        std::smatch sm;
        std::string searchText = "Peter ist 70 Jahre alt und hat bereits Probleme sich die Schuhe anzuziehen.Peter ist 80 Jahre alt und hat bereits Probleme sich die Schuhe anzuziehen.";
    
        while(std::regex_search(searchText, sm, re))
        {
            std::cout << "entire match: " << sm.str() << "\n";
            for (std::size_t i = 1; i < sm.size(); ++i)
                std::cout << "capture group " << i << ": " << sm[i].str() << "\n";
            searchText = sm.suffix();
        }
    }
    

    Pass das für deine Qt bedürfnisse an.
    Das geht sich besser, weil searchText = sm.suffix(); ist jetzt nicht das performanteste auf der Welt, aber ich hab das schnell zusammenschmissen.



  • Du kannst auch einen regex_iterator nutzen:

    std::regex re(R"(Peter ist (\d+) Jahre alt)");
    std::string s("Peter ist 70 Jahre alt. Oder: Peter ist 60 Jahre alt?");
    auto resultIt = std::sregex_iterator(s.begin(), s.end(), re);
    for (auto it = resultIt; it != std::sregex_iterator(); ++it) {
        std::cout << "Ganzer Match: |" << it->str() << "|, das Alter ist: |" << (*it)[1].str() << "|\n";
    }
    


  • Da @DerDaVinciKot Qt in seinem Projekt verwendet schmeiß ich mal in dem Raum, dass Qt auch selbst eine Regex klasse hat. https://doc.qt.io/qt-5/qregularexpression.html



  • Hey, Ihr seid echt spitze! Beide Codes funktionieren. Ich werde mich da mal durcharbeiten damit ich das ganze auch wirklich verstehe.

    Ein schönes Wochenende noch


Log in to reply