سؤال

I am trying to learn the regular expressions in C++11. Must be doing something wrong since no brackets or escape sequences seem to work.

Here is my code:

#include <iostream>
#include <regex>
#include <string>

using namespace std;

int main()
{
    try
    {
        cout << R"(\d*(\.\d*)?;)" << endl << endl;

        regex rx{ R"(\d*(\.\d*)?;)", regex_constants::ECMAScript };
        smatch m;

        if( regex_match( string( "10;20;30;40;" ), m, rx ) )
        {
            cout << m[0];
        }
    }
    catch( const regex_error &e )
    {
        cerr << e.what() << ". Code: " << e.code() << endl;

        switch( e.code() )
        {
        case regex_constants::error_collate:
            cerr << "The expression contained an invalid collating element name.";
            break;
        case regex_constants::error_ctype:
            cerr << "The expression contained an invalid character class name.";
            break;
        case regex_constants::error_escape:
            cerr << "The expression contained an invalid escaped character, or a trailing escape.";
            break;
        case regex_constants::error_backref:
            cerr << "The expression contained an invalid back reference.";
            break;
        case regex_constants::error_brack:
            cerr << "The expression contained mismatched brackets ([ and ]).";
            break;
        case regex_constants::error_paren:
            cerr << "The expression contained mismatched parentheses (( and )).";
            break;
        case regex_constants::error_brace:
            cerr << "The expression contained mismatched braces ({ and }).";
            break;
        case regex_constants::error_badbrace:
            cerr << "The expression contained an invalid range between braces ({ and }).";
            break;
        case regex_constants::error_range:
            cerr << "The expression contained an invalid character range.";
            break;
        case regex_constants::error_space:
            cerr << "There was insufficient memory to convert the expression into a finite state machine.";
            break;
        case regex_constants::error_badrepeat:
            cerr << "The expression contained a repeat specifier (one of *?+{) that was not preceded by a valid regular expression.";
            break;
        case regex_constants::error_complexity:
            cerr << "The complexity of an attempted match against a regular expression exceeded a pre-set level.";
            break;
        case regex_constants::error_stack:
            cerr << "There was insufficient memory to determine whether the regular expression could match the specified character sequence.";
            break;
        default:
            cerr << "Undefined.";
            break;

}

    cerr << endl;
}

    return 0;
}

Output:

\d*(.\d*)?;

regex_error. Code: 2

The expression contained an invalid escaped character, or a trailing escape.

What am I doing wrong?

Update

gcc version 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC)

clang version 3.3 (tags/RELEASE_33/final)

libstdc++ version 4.8.2

Solution

Well. I am reading "The C++ programming language" and wanted to experiment with the std::regex stuff. So I guess the solution is to wait for gcc-4.9.

I gave EagleV_Attnam the credit for pointing out other errors in my code.

هل كانت مفيدة؟

المحلول

Two things:

  1. Your string "10;20;30;40;"is only defined in the match_regex call. An smatch, as opposed to cmatch, expects the string (as in, the one created by string()) to still be alive by the time you want to access it.
  2. Your current regex doesn't match (at least not on my system). It tries to match the whole string. Adding a .* at the end (and start, but that's not necessary in your case) should fix it, as would letting the whole thing repeat (with R"((stuff)*)")

Working code (but couldn't try it on gcc):

regex rx{ R"(\d*(\.\d*)?;.*)", regex_constants::ECMAScript };
smatch m;
string s("10;20;30;40;");
if (regex_match(s, m, rx))
{
    cout << m[0];
}

Don't know if that will fix your particular error - I'm afraid KitsuneYMG is right on that count - but it shouldn't hurt to try.

نصائح أخرى

One issue with your regexp is you are not escaping \ and \d is not a valid escape sequence in the context of a string. I'm unsure if you can use an R identifier on the string but it was undefined for me.

Also GCC's regexp was incomplete last time I checked. So you may be forced to use boost regexp.

    regex rx( "\\d*;" ); //regexp, must escape '\'
    string input = "10;20;30;40;";
    smatch m;

    if( regex_search( input, m, rx ) )
    {
        cout << m[0] << endl;
    } 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top