1

My code is to use regex match group for 5 thing this is my code :

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

using namespace std;
int main(){


    try{

        string input("(66+89i)+(12+5i)");

        regex re("([\\d]+)([+\\-]?[\\di]+)\\)([+\\-*=\\/!]+)\\(([\\d]+)([+\\-]?[\\di]+)");
        smatch match;

        if (regex_search(input, match, re)) {

            cout << "x1 : " << match.str(1)<<endl;
            cout << "y1 : " << match.str(2)<<endl;
            cout << "operator : " << match.str(3)<<endl;
            cout << "x2 : " << match.str(4)<<endl;
            cout << "y2 : " << match.str(5)<<endl;

        }
        else {
            cout << "No match is found" << endl;
        }


    } catch (std::regex_error r) {
        cout<<r.what();
    }


    return 0;
}

when I run this code i get this error " Invalid range in bracket expression." how can i fix this ?

UPDATE : this code works in c++17, but in c++14 I get an error! in this compiler link is not work

natar moon
  • 21
  • 2

2 Answers2

1

Note that it was a bug fixed in g++ 7.x for all standards that has never been present in C++1z/C++17. The onlinegdb platform uses an old g++ 5.4.1 version where the bug was still present (see @brc-dd comment).

See Bug 77356 - regex error for a ECMAScript syntax string and Bug 77469 - std::regex x("[b\-a]") throws with message "Invalid range in bracket expression." describing the bug. The idea is that ECMAScript syntax acutally allows an escaped hyphen in any position inside a character class, while POSIX standard disallows it (it does not allow regex escapes inside bracket expressions).

The problem here is that even when the hyphen is escaped inside a character class, the regex won't match. The only way to use the hyphen here is by placing it either at the start or end of the character class.

Also, you'd better use a raw string literal to define the regex pattern.

You may use

regex re(R"~~~((\d+)([+-]?[\di]+)\)([+*=/!-]+)\((\d+)([+-]?[\di]+))~~~");

Output of the updated demo:

x1 : 66
y1 : +89i
operator : +
x2 : 12
y2 : +5i

Here,

  • R"~~~(...)~~~" - a raw string literal declaration, \ are literal backslashes here that do not form string escape sequences (so, \t is not a tab, it is a two-char combination, \ and t, although it will still match a tab)
  • (\d+) - Group 1: one or more digits
  • ([+-]?[\di]+) - Group 2: an optional + or - and then 1+ digits or i char
  • \) - a )
  • ([+*=/!-]+) - Group 3: one or more +, *, =, /, ! or -
  • \( - a ( char
  • (\d+) - Group 4: 1+ digits
  • ([+-]?[\di]+) - Group 5: an optional + or - and then 1+ digits or i char

Note: you do not need to escape a / char, it is not any special regex metacharacter in regex. Since C++ patterns are defined with string literals, not regex literals that often utilize / as regex delimiter chars, you do not need to put \ in front of it here.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • It is not exactly a "quirk" with `std::regex` itself. It was a bug fixed in `g++ 7.x` for all standards (never present in `C++1z`/`C++17`). The *onlinegdb* platform uses a 5 year old version, i.e. `g++5.4.1` which was causing the problem. – brc-dd Jul 04 '20 at 19:52
  • @brc-dd Good to know. The point is still the same, `-` is always better to be used at the start or end of the character classes/bracket expressions to avoid any problems like this. Is there an SO thread already explaining this? – Wiktor Stribiżew Jul 04 '20 at 19:56
  • [Regex - Should hyphens be escaped?](https://stackoverflow.com/questions/9589074/regex-should-hyphens-be-escaped) and [How to match hyphens with Regular Expression?](https://stackoverflow.com/questions/4068629/how-to-match-hyphens-with-regular-expression) : These seems quite similar to the fact you wanna explain here. – brc-dd Jul 04 '20 at 20:01
  • @brc-dd I know them, but in context of C++, these are not enough. I'd close with them right away, but the problem here is that even when `-` is escaped inside a character class, it does not work. I will include the details of the bug you mentioned. – Wiktor Stribiżew Jul 04 '20 at 20:03
  • 1
    Here is the bug ID: [77356](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77356) if you want a reference to it. – brc-dd Jul 04 '20 at 20:11
0

It appears C++14 has a bug in the Regex parser.
Any escaped dash "[\\-]" no matter where it is parsed to be
an unescaped dash [-], i.e. a range operator.
This is a BUG.

It does however still honor it being a literal dash if it is at the
beginning or end of the class.

C++l7 (works) https://onlinegdb.com/S1rH3rCRI

C++l4 (bug) https://onlinegdb.com/Bya3jSR0I

C++

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

using namespace std;
int main(){


    try{ string rs1 = "[+\\-*=/!]"; cout<<rs1<<" --> "; regex re( rs1 );  } catch (std::regex_error r) {
        cout<<"The error is: "<<r.what();
    }

   try{ string rs2 = "[+\\-]"; cout<<"\n"<<rs2<<" --> "; regex re( rs2 ); } catch (std::regex_error r) {
        cout<<"The error is: "<<r.what();
    }

   try{
        string rs3 = "[\\-+]"; cout<<"\n"<<rs3<<" --> "; regex re( rs3 ); } catch (std::regex_error r) {
        cout<<"The error is: "<<r.what();
    }

   try{
        string rs4 = "[+-]"; cout<<"\n"<<rs4<<" --> "; regex re( rs4 ); } catch (std::regex_error r) {
        cout<<"The error is: "<<r.what();
    }

   try{
        string rs5 = "[-+]"; cout<<"\n"<<rs5<<" --> "; regex re( rs5 ); } catch (std::regex_error r) {
        cout<<"The error is: "<<r.what();
    }

    try{ string rs6 = "[-+*=/!]"; cout<<"\n"<<rs6<<" --> "; regex re( rs6 );  } catch (std::regex_error r) {
        cout<<"The error is: "<<r.what();
    }

    return 0;
}

Results (C++14)

[+\-*=/!] --> The error is: Invalid range in bracket expression.                                                                 
[+\-] -->                                                                                                                        
[\-+] -->                                                                                                                        
[+-] -->                                                                                                                         
[-+] -->                                                                                                                         
[-+*=/!] -->  
  • I noticed @WiktorStribiżew your original answer was `It is a common C++ std::regex ECMAScript flavor "quirk"`, is that a JavaScript problem that bled through to the C++ standard ? Brcause, usually _COMPILERS_ are linked to the _Std_ libraries that do the _regex parsing and construction_, not the compilers ! –  Jul 04 '20 at 20:17