std=c++11 和 std=gnu++11 之间的 C++ 标准正则表达式差异
C++ standard regex difference between std=c++11 and std=gnu++11
使用正则表达式和 gnu 扩展编译代码时,正则表达式的行为似乎有所不同。
以下代码在使用 -std=c++11 编译时产生异常,但是 -std=gnu++11 有效:
#include <regex>
#include <iostream>
int main(int argc, char **argv) {
std::string rex { "\[1\]" };
std::string str { "[1]" };
std::regex regex(rex, std::regex::extended);
auto match = std::regex_match(str.begin(), str.end(), regex);
std::cout << "Result is " << match << std::endl;
return 0;
}
我尝试了从 4.9.4 到 9.2 的 gcc,但行为相同。知道为什么这段代码的行为不同吗?
std::regex::extended
使用 extended POSIX regular expressions。根据这些语法规则,反斜杠只能放在 "special character" 之前,它是 .[\()*+?{|^$
之一。左括号 [
是特殊字符,而右括号 ]
不是。所以你的正则表达式应该是 "\[1]"
而不是 "\[1\]"
才符合标准。
查看标准库源码,regex_scanner.tcc中有如下内容:
#ifdef __STRICT_ANSI__
// POSIX says it is undefined to escape ordinary characters
__throw_regex_error(regex_constants::error_escape,
"Unexpected escape character.");
#else
_M_token = _S_token_ord_char;
_M_value.assign(1, __c);
#endif
这表明它是允许转义非特殊字符的 GNU 扩展。我不知道这个扩展在哪里记录。
使用正则表达式和 gnu 扩展编译代码时,正则表达式的行为似乎有所不同。
以下代码在使用 -std=c++11 编译时产生异常,但是 -std=gnu++11 有效:
#include <regex>
#include <iostream>
int main(int argc, char **argv) {
std::string rex { "\[1\]" };
std::string str { "[1]" };
std::regex regex(rex, std::regex::extended);
auto match = std::regex_match(str.begin(), str.end(), regex);
std::cout << "Result is " << match << std::endl;
return 0;
}
我尝试了从 4.9.4 到 9.2 的 gcc,但行为相同。知道为什么这段代码的行为不同吗?
std::regex::extended
使用 extended POSIX regular expressions。根据这些语法规则,反斜杠只能放在 "special character" 之前,它是 .[\()*+?{|^$
之一。左括号 [
是特殊字符,而右括号 ]
不是。所以你的正则表达式应该是 "\[1]"
而不是 "\[1\]"
才符合标准。
查看标准库源码,regex_scanner.tcc中有如下内容:
#ifdef __STRICT_ANSI__
// POSIX says it is undefined to escape ordinary characters
__throw_regex_error(regex_constants::error_escape,
"Unexpected escape character.");
#else
_M_token = _S_token_ord_char;
_M_value.assign(1, __c);
#endif
这表明它是允许转义非特殊字符的 GNU 扩展。我不知道这个扩展在哪里记录。