Boost:: Parsen und Datum



  • Hallo mal wieder.
    Ich hätte da mal 2 Fragen:

    1. Parsen mit Boost
    Ich bekomme in meinem Programm einen String geliefert den ich auf richtigkeit prüfe, das sieht so aus:

    //So könnte ein String aussehen:
    //login_name=TestName&login_password=Testpwd&login_senden=Senden
    static const boost::regex e("login_name[=][a-zA-ZöäüÖÄÜ]{1,20}[&]login_password[=][a-zA-ZöäüÖÄÜ]{1,20}[&]login_senden=Senden");
    reg_resultLogin = regex_match(s, e);
    
    if(reg_resultLogin)//ok oder Fehler
    

    Das funktioniert wunderbar.
    Aber aus diesem oben beschriebenen String sollte ich nun den Namen und das Passwort extrahieren.(std::string Name, std::string Passwort)
    Ich weiß das daß mit boost::regex_irgendwas geht.
    Nur wie und mit was?

    Weiß das jemand?

    Das
    2. Datum mit boost.

    Ich ermittle das Datum so:

    char buf[45];
    memset(buf,0,45);
    
    SYSTEMTIME systime;
    GetLocalTime(&systime);
    sprintf(buf,"%02d.%02d.%d ",systime.wDay,systime.wMonth,systime.wYear);
    

    Geht auch wunderbar.
    Nur interessiert mich wie das mit boost geht?
    Habe mal durch die Doku gewühlt, da steht so viel...
    Ich frage vor allem im Hinblick, da ich später eine Lösung haben sollte, bei der ich von einem Bestimmten Datum die Kalenderwoche haben sollte.
    Wie geht das (mit boost)?

    Vielen Dank für die Hilfe, Mondmann



  • Für das Datum brauchst du kein Boost, das geht auch mit Ansi-Funktionen: time() liefert die aktuelle Systemzeit (inklusive Datum) und gmtime() bastelt dir daraus eine verwertbare struct.

    (für die Kalenderwoche kannst du den Wert tm_yday auswerten, du mußt nur aufpassen, was als "erste Woche" gezählt wird.



  • Ich glaube wegen der KW habe ich schonmal nen Thread geschrieben, das funktioniert nicht, warum weiß ich jetzt nimmer.
    Mal lesen.

    Und die Regex Geschichte?



  • Mondmann schrieb:

    Ich glaube wegen der KW habe ich schonmal nen Thread geschrieben, das funktioniert nicht, warum weiß ich jetzt nimmer.
    Mal lesen.

    Was meinst du mit "funktioniert nicht"?

    Und die Regex Geschichte?

    Da mußt du auf einen Kollegen warten, weil ich mich mit Boost::Regex nicht auskenne.

    (btw, für die Zukunft solltest du besser für jedes Problem einen eigenen Thread eröffnen ;))



  • Die Substrings die du haben willst must du in der regex in Klammern setzen, in deinem Fall also so

    //So könnte ein String aussehen:
    //login_name=TestName&login_password=Testpwd&login_senden=Senden
    static const boost::regex e("login_name[=]([a-zA-ZöäüÖÄÜ]{1,20})[&]login_password[=]([a-zA-ZöäüÖÄÜ]{1,20})[&]login_senden=Senden");
    reg_resultLogin = regex_match(s, e);
    
    if(reg_resultLogin)//ok oder Fehler
    

    Wie du dann darauf zugreifst kannst du hier nachlesen
    http://www.boost.org/libs/regex/doc/captures.html



  • Wenn ich es also so mache, funktionierts ganz hervorragend:

    static const boost::regex e("login_name[=]([a-zA-ZöäüÖÄÜ]{1,20})[&]login_password[=]([0-9a-zA-ZöäüÖÄÜ]{1,20})[&]login_senden=Senden		
    		boost::match_results<std::string::const_iterator> loginErg;
    		reg_resultLogin = boost::regex_match(s, loginErg, e, boost::match_default | boost::match_partial);
    
    		std::string nam(loginErg[1]);
    		std::string pwd(loginErg[2]);
    

    Dann stehen in nam und pwd meine gewünschten Werte.
    Vielen Dank das war sehr hilfreich!

    Die Frage ist nun, ob das schneller ist als wie vorher:

    1.Prüfen ob der String korrekt ist.
    2. Mit s.find("login_name");
    ...

    pwd= s.substr("...");

    Die zwei (später auch mehr) Werte auszulesen????
    Ist das mit Regex nun schneller?
    Bequemer und Platzsparender auf jeden Fall...
    Mondmann



  • So ,jetzt ahbe ich noch ein Problem mit einem Regulären Ausdruck.
    Er gibt 1 zurück, obwohl er nicht passen dürfte:

    unsigned int reg_resultBuch = 0;
    boost::match_results<std::string::const_iterator> buchErg;
    static const boost::regex dialogbuch("^weiter[=].{1,20}[&]buchart[=]([A-Z a-z]{2,5})[&]eingabeDatum[=]([0-9.]{10})[&]eingabeUhrzeit[=]([0-9:]{5})$");
    
    std::string buchi = reinterpret_cast<char* >(pbuch->lpbData);
    
    reg_resultBuch = boost::regex_match(buchi, buchErg, dialogbuch, boost::match_default | boost::match_partial);
    

    Der String der da ankommt ist:

    weiter=T1dHRh5OHlc=&buchart=KO

    Trotzdem gibt die regex Funktion 1 zurück...wieso?
    Was klar ist, der String passt zum Teil.
    Aber ich habe doch das ^...$, damit lege ich doch fest, daß er den ganzen String prüfen soll, oder?



  • Keiner eine Idee?
    Habs nochmal geprüft, sollte eigentlich stimmen...



  • 1. Warum schreibst Du "=" und "&" in eckigen Klammern?
    2. in Deinem "eingabeDatum" solltest Du den "." escapen
    3. bei mir gibt die funktion nicht 1 zurück bei Deinem Teststring



  • 1. Weil das Zeichen genau an dieser Stelle sein soll.
    Man könnte es auch weglassen.

    2. Warum? Der Punkt steht doch in einer eckigen Klammer, was bedeutet, daß Zahlen (0-9) und Punkte vorkommen dürfen.
    Oder sehe ich das falsch?

    3. Bei mir leider doch...

    Grüße Mondmann



  • Mondmann schrieb:

    1. Weil das Zeichen genau an dieser Stelle sein soll.
    Man könnte es auch weglassen.

    Dann müsstest Du nicht schreiben "Ein beliebiges Zeichen aus der Menge (&)", sondern "Null oder einmal das Zeichen '&'", sprich "&?" statt "[&]".

    2. Warum? Der Punkt steht doch in einer eckigen Klammer, was bedeutet, daß Zahlen (0-9) und Punkte vorkommen dürfen.

    Können allerdings auch zehn Punkte sein...



  • . steht eigentlich immer für ein beliebiges Zeichen. Schreib lieber mal \.



  • Ja des stimmt.
    Da ich aber[&]schreibe ist es doch so korrekt(?).
    Wenns 10 Punkte sind , ist es auch egal...

    Ich frage mich warum der String dein ch unten gepostet habe 1 ergibt.
    Das muss damit etwas zu tun haben, daß es ein Teilstring ist...



  • Stimmt, es können auch zehn beliebige Zeichen sein. Auch in einer Menge steht der Punkt für "jedes beliebige Zeichen".

    [&] ist, nochmal, "ein Zeichen aus der Menge" - sprich entweder &, oder &, oder &, oder... (verstehst Du worauf ich hinaus will - die Mengenklammer ist hier sinnlos). Weglassen darfst Du das & allerdings nicht, weil "nichts" nicht der Regel "ein Zeichen aus der Menge" gehorcht.



  • Mondmann schrieb:

    1. Weil das Zeichen genau an dieser Stelle sein soll.
    Man könnte es auch weglassen.

    2. Warum? Der Punkt steht doch in einer eckigen Klammer, was bedeutet, daß Zahlen (0-9) und Punkte vorkommen dürfen.
    Oder sehe ich das falsch?

    Du solltest Dir die RE-Syntax nochmal durchlesen...

    Mondmann schrieb:

    3. Bei mir leider doch...

    ...und die Doku zu Boost::regex (bzgl. match_partial).
    Wahrscheinlich hast Du Dein gewünschtes Ergebnis, wenn Du es weglässt.



  • Hm...bin mir nicht ganz sicher.
    Also sollte ich das & escapen oder [&]{1} schreiben und den Punkt in den eckigen Klammern ebenfalls escapen.

    Das sähe denn so aus:

    static const boost::regex dialogbuch("^weiter=.{1,20}[&]{1}buchart=([A-Z a-z]{2,5})[&]{1}eingabeDatum=([0-9\.]{10})[&]{1}eingabeUhrzeit=([0-9:]{5})$");
    

    Was aber leider keinerlei Besserung bringt.
    Das Ergebnis ist immer 1 beim String:

    weiter=T1dHRh5OHlc=&buchart=KO

    Was ist dann noch falsch?



  • Airdamn schrieb:

    Mondmann schrieb:

    1. Weil das Zeichen genau an dieser Stelle sein soll.
    Man könnte es auch weglassen.

    2. Warum? Der Punkt steht doch in einer eckigen Klammer, was bedeutet, daß Zahlen (0-9) und Punkte vorkommen dürfen.
    Oder sehe ich das falsch?

    Du solltest Dir die RE-Syntax nochmal durchlesen...

    Mondmann schrieb:

    3. Bei mir leider doch...

    ...und die Doku zu Boost::regex (bzgl. match_partial).
    Wahrscheinlich hast Du Dein gewünschtes Ergebnis, wenn Du es weglässt.

    Stimmt haste recht!
    Hab Deinen Post zu späte gelesen, drum der vorherige.

    Werde mir doe Doku reinziehen, kanns mir aber denken was partial bedeitet 😡

    So ist es, wenn man Beispiele einfach reinkopiert ohne es zu verstehen.
    Habt sackrisch Dank für die Hilfe...
    Mondmann



  • Nur damit wir uns verstehen, das ganze sollte in etwa so aussehen:

    string url = "weiter=T1dHRh5OHlc=&buchart=KO";
    string re = "^weiter=.{1,20}&buchart=([A-Z a-z]{2,5})&eingabeDatum=([0-9\\.]{10})&eingabeUhrzeit=([0-9:]{5})$";
    boost::regex e(re);
    boost::cmatch results;
    bool match = boost::regex_match(url.c_str(), results, e);
    if(match)
    {
    	for(boost::cmatch::iterator it = results.begin()+1; it != results.end(); ++it)
    		cout << *it << endl;
    }
    

Anmelden zum Antworten