Different behavior in C regex vs C++ regex using extended POSIX grammar

Viewed 250

I am seeing different results when using the C POSIX regex library and the C++ standard library implementation. Here is my code:

string pattern = "\\s";
string testString = " ";

regex_t cre;
int status = regcomp(&cre, pattern.c_str(), REG_EXTENDED);
int result = (regexec(&cre, testString.c_str(), 0, 0, 0) == 0);
cout << "C: " << result << endl;

regex re(pattern, regex_constants::extended);
smatch sm;
cout << "C++: " << regex_search(testString, sm, re) << endl;

The C portion successfully matches the whitespace, but the C++ one throws this error:

terminate called after throwing an instance of 'std::regex_error'
what(): Unexpected escape character.

I understand that the string literal is escaped meaning that the actual regex that is used in pattern matching should be \s. I also only see this issue when using POSIX extended grammar. In the C++ version, if I do not specify POSIX extended grammar when constructing the regex, it defaults to ECMAScript grammar and is able to parse correctly.

What is going on here?

2 Answers

regex_constants::extended triggers the POSIX ERE regex syntax that does not support shorthand character classes. Note the C regex.h module supports \s as a non-standard extension.

To match any whitespace in regex_constants::extended enabled POSIX ERE flavor, you need to use string pattern = "[[:space:]]".

However, you should just rely on the default ECMAScript flavor, and use

regex re(pattern);
// or
regex re(pattern, std::regex::ECMAScript);

In Posix REs

The effect of any ordinary character being preceded by an escape is undefined.

(from boost docs)

9.4.2 ERE Ordinary Characters

An ordinary character is an ERE that matches itself. An ordinary character is any character in the supported character set, except for the ERE special characters listed in ERE Special Characters. The interpretation of an ordinary character preceded by an unescaped ( '\' ) is undefined, except in the context of a bracket expression (see ERE Bracket Expression).

(from posix docs )

Similar wording applies to BREs.

So both are posix compliant, as your RE is undefined in effect.

Related