1

I'm new to regex and C++11. In order to match an expression like this :

TYPE SIZE NUMBER ("regina s x99");

I built a regex which looks like this one :

\b(regina|margarita|americaine|fantasia)\b \b(s|l|m|xl|xxl)\b x([1-9])([0-9])

In my code I did this to try the regex :

std::string s("regina s x99");
std::regex rgx($RGX); //$RGX corresponds to the regex above
if (std::regex_match(s, rgx))
std::cout << "It works !" << std::endl;

This code throw a std::regex_error, but I don't know where it comes from..

Thanks,

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
Nicolas Charvoz
  • 1,509
  • 15
  • 41

3 Answers3

1

In C++ strings the \ character is special and needs to be escaped so that it gets passed to the regular expression engine, not interpreted by the compiler.

So you either need to use \\b:

std::regex rgx("\\b(regina|margarita|americaine|fantasia)\\b \\b(s|l|m|xl|xxl)\\b x([1-9])([0-9])");

or use a raw string, which means that \ is not special and doesn't need to be escaped:

 std::regex rgx(R"(\b(regina|margarita|americaine|fantasia)\b \b(s|l|m|xl|xxl)\b x([1-9])([0-9]))");
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

This works with g++ (4.9.2) in c++11 mode:

std::regex rgx("\\b(regina|margarita|americaine|fantasia)\\b\\s*(s|l|m|xl|xxl)\\b\\s*x([1-9]*[0-9])"); 

This will capture three groups: regina s 99 which matches the TYPE SIZE NUMBER pattern, while your original captured four groups regina s 9 9 and had the NUMBER as two values (maybe that was what you wanted though).

Demo on IdeOne

jpw
  • 44,361
  • 6
  • 66
  • 86
  • The last group can (and probably should) be tweaked a bit depending on the range of the NUMBER you want to match (if it has a leading 0 or not. Maybe it should be `x([1-9]+[0-9]*)` for `1 to N` – jpw Apr 17 '15 at 11:20
0

There was a typo in this line in original question:

if (std::reegex_match(s, rgx))

More over I am not sure what are you passing with this variable : $RGX

Corrected program as follows:

#include<regex>
#include<iostream>
int main()
{
    std::string s("regina s x99");
std::regex rgx("\\b(regina|margarita|americaine|fantasia)\\b \\s*(s|l|m|xl|xxl)\\b \\s*x([1-9])([0-9])"); //$RGX corresponds to the regex above
if (std::regex_match(s, rgx))
std::cout << "It works !" << std::endl;
else
  std::cout<<"No Match"<<std::endl;
}
Steephen
  • 14,645
  • 7
  • 40
  • 47
  • Yeah copy/paste does not work between VMWare and MAC Os X, there is no typo in my code, and the variable $RGX does not exist in my code, I didn't want to rewrite the regex again. I thought it was clearer this way. – Nicolas Charvoz Apr 17 '15 at 10:59
  • @Steephen You need to escape your slashes or this will never match. – Jonathan Mee Apr 17 '15 at 11:00
  • @Jonathan Mee I was just using the pattern he tried, I will correct it – Steephen Apr 17 '15 at 11:00
  • @JonathanMee corercted it is matching now – Steephen Apr 17 '15 at 11:02
  • 1
    @Steephen, since the OP said he gets a `regex_error` I think it's safe to assume the code compiled, and so there's no typo in the original. Also, you apparently didn't test your corrected code, it still doesn't match. – Jonathan Wakely Apr 17 '15 at 11:03
  • @JonathanWakely There was a typo, he corrected after see the answer!! I tested the code after correction before posting and it works – Steephen Apr 17 '15 at 11:05
  • I know there was a typo in **the question** but that obviously wasn't the cause of the `regex_error` exception. – Jonathan Wakely Apr 17 '15 at 11:06
  • @JonathanWakely I didn't mean typo is the reason for regex_error – Steephen Apr 17 '15 at 11:08