2

I am trying to do regex_match on a string which have square brackets([...]) inside it.

Things I have tried so far:

  • Normal matching
  • Backslashing the square brackets with 1 slash
  • Backslashing the square brackets with 2 slashes

Code to repro:

#include <iostream>
#include <cstring>
#include <regex>

using namespace std;

int main () {
  std::string str1 = "a/b/c[2]/d";
  std::string str2 = "(.*)a/b/c[2]/d(.*)";
  std::regex e(str2);

  std::cout << "str1 = " << str1 << std::endl;
  std::cout << "str2 = " << str2 << std::endl;
  if (regex_match(str1, e)) {
    std::cout << "matched" << std::endl;
  }
}

This is the error message I get every time I compile it.

terminate called after throwing an instance of 'std::regex_error'
what():  regex_error
Aborted (core dumped)

I was told by stack overflow members that gcc 4.8 or earlier version of it are known to be buggy. So, I needed to update it to latest version.

I have created an Ideone fiddle where compiler should not be issue. Even there, I do not see regex_match happening.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Hemant Bhargava
  • 3,251
  • 4
  • 24
  • 45

3 Answers3

2

The main problem you have is the outdated gcc compiler: you need to upgrade to some recent version. 4.8.x just does not support regex as it should.

Now, the code you should be using is:

#include <iostream>
#include <cstring>
#include <regex>

using namespace std;

int main () {
    std::string str1 = "a/b/c[2]/d";
    std::string str2 = R"(a/b/c\[2]/d)";
    std::regex e(str2);

    std::cout << "str1 = " << str1 << std::endl;
    std::cout << "str2 = " << str2 << std::endl;
    if (regex_search(str1, e)) {
        std::cout << "matched" << std::endl;
    }
}

See the IDEONE demo

Use

  • regex_search instead of regex_match to search for partial matches (regex_match requires a full string match)
  • The [2] in the regex pattern matches a literal 2 ([...] is a character class matching 1 character from the range/list specified in the character class). To match the literal square brackets, you need to escape the [ and you do not have to escape ]: R"(a/b/c\[2]/d)".
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

Well they should definitely be escaped by using a backslash. Unfortunately since backslash is itself special in a literal string you need two backslashes. So the regex should look like "(.*)a/b/c\\[2\\]/d(.*)".

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Raw string literals often simplify cases where one would otherwise have to have complex escape sequences:

#include <iostream>
#include <cstring>
#include <regex>

using namespace std;

int main () {
    std::string str1 = "a/b/c[2]/d";
    std::string str2 = R"regex((.*)a/b/c[2]/d(.*))regex";
    std::regex e(str2);

    std::cout << "str1 = " << str1 << std::endl;
    std::cout << "str2 = " << str2 << std::endl;
    if (regex_match(str1, e)) {
        std::cout << "matched" << std::endl;
    }
}

expected output:

str1 = a/b/c[2]/d
str2 = (.*)a/b/c[2]/d(.*)
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142