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 扩展。我不知道这个扩展在哪里记录。