2016-11-02 6 views
1

Ich habe eine Regex für übereinstimmende Terme eines Polynoms, die ich verwenden werde, um eine Funktion zu implementieren, um einen String in eine Polynomklasse zu verwandeln. Sie können die Regex-Demo here mit den richtigen Übereinstimmungen sehen, die erzeugt werden. Wenn ich jedoch versuche, es zu implementieren, findet mein Programm die Übereinstimmungen richtig, aber druckt sie bizarr auf dem Bildschirm. Zum Beispiel:Warum stimmt meine C++ Regex korrekt überein, gibt aber nicht den richtigen Wert zurück?

-21323x^5+1233x4+123x^2-1232 
Trying to match: -21323x^5+1233x4+123x^2-1232 
-21323x^5 
Trying to match: +1233x4+123x^2-1232 
1233x4 
Trying to match: +123x^2-1232 
12xx^2 
Trying to match: -1232 
-1232 

In diesem Fall aus irgendeinem Grund druckt es 12xx^2 statt 123x^2

Und ein anderer:

-1234x^5+789x4+6x^2-567+123x 
Trying to match: -1234x^5+789x4+6x^2-567+123x 
-1234x^5 
Trying to match: +789x4+6x^2-567+123x 
789x4 
Trying to match: +6x^2-567+123x 
x^22 
Trying to match: -567+123x 
-567 
Trying to match: +123x 
23xx 

In diesem Fall zeigt es x^22 statt 6x^2 und 23xx statt 123x.

Dies ist mein Code:

Poly* Poly::fromString(std::string str) { 
    Poly* re = new Poly; 
    bool returnNull = true; 
    std::regex r_term("((-?[0-9]*)x(\\^?([0-9]+))?|-?[0-9]+)"); 
    std::smatch sm; 
    while(std::regex_search(str, sm, r_term)) { 
     returnNull = false; 
     std::cout << "Trying to match: " << str << std::endl; 
     str = sm.suffix().str(); 
     std::cout << sm.str() << std::endl; 
    } 

    if(returnNull) { 
     delete re; 
     return nullptr; 
    } else return re; 
} 
+1

Verschieben Sie die Zuweisung 'str = sm.suffix(). Str();' unterhalb der Zeile, in der Sie 'sm.str()' drucken. 'smatch' enthält keine Kopie der Übereinstimmung, nur Iteratoren in der ursprünglichen Zeichenfolge. Wenn Sie die Zeichenfolge darunter ändern, macht Ihr Programm diese Iteratoren ungültig und weist daher ein undefiniertes Verhalten auf. –

+0

Das macht Sinn. Vielen Dank. Bitte fügen Sie dies als Antwort hinzu. –

Antwort

0

Während Igor richtig das Problem mit Ihrem aktuellen Code bemerkt, ich glaube, alles, was Sie brauchen, ist volle Muster übereinstimmt, und zu diesem Zweck zu bekommen, würde ich eher vorschlagen, mit ein regex Iterator:

std::regex r("(-?[0-9]*)x(\\^?([0-9]+))?|-?[0-9]+"); 
std::string s = "-21323x^5+1233x4+123x^2-1232"; 
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r); 
         i != std::sregex_iterator(); 
         ++i) 
{ 
    std::smatch m = *i; 
    std::cout << "Match value: " << m.str() << '\n'; 
    std::cout << "Group 1 value: " << m.str(1) << '\n'; 
    std::cout << "Group 2 value: " << m.str(2) << '\n'; 
    std::cout << "Group 3 value: " << m.str(3) << '\n'; 
} 

die C++ demo online See.

Die Musterdetails:

  • -? - 1 oder 0 Bindestriche
  • [0-9]*-0 oder mehr Ziffern
  • x - eine wörtliche char x
  • (\\^?([0-9]+))?-1 oder 0 Sequenzen von:
    • \\^? - eine Option nal (1 oder 0) ^ Symbole
    • [0-9]+-1 oder mehr Ziffern
  • | - oder
  • -? - ein optionaler Bindestrich/minus
  • [0-9]+-1 oder mehr Ziffern.
+0

Ich bin eigentlich interessiert Submatches zu verwenden, da es mir erlaubt, sofort auf meinen Koeffizienten und meine Macht zuzugreifen. –

+0

Ok, behalte sie, aber ich würde immer noch vorschlagen, die äußeren Klammern zu entfernen, da die ganze Übereinstimmung bereits innerhalb der Gruppe 0 ist. Außerdem benötigt der Iterator keine Kopie der ursprünglichen Zeichenfolge, die während der Codeausführung zerstört wird . –

+0

Ich stimme zu, das scheint eine bessere Idee zu sein. Der Grund, warum ich die äußere Spielgruppe hatte, war, dass ich irrtümlich geglaubt habe, dass du sie brauchst, um | Regex-Operator. –

Verwandte Themen