std :: regex构造函数抛出异常

时间:2016-01-07 20:30:37

标签: c++ regex c++11

请注意,这与不是是关于gcc的StackOverflow上的许多问题的重复,我正在使用Visual Studio 2013.

正则表达式的这种简单构造抛出javac

std::regex_error

bool caseInsensitive = true; char pattern[] = "\\bword\\b"; std::regex re(pattern, std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0)); 在异常对象上返回的实际错误不一致。通常它是一个不匹配的parethesis或支撑。为什么呢?

2 个答案:

答案 0 :(得分:11)

问题出现是因为what可用的多个构造函数。跟踪构造函数显示它使用了我不想要的那个!

我想用这个:

std::regex

但我得到了这个:

explicit basic_regex(_In_z_ const _Elem *_Ptr,
    flag_type _Flags = regex_constants::ECMAScript)

标志中的三元表达式导致类型更改为basic_regex(_In_reads_(_Count) const _Elem *_Ptr, size_t _Count, flag_type _Flags = regex_constants::ECMAScript) ,它不再与构造函数签名中的int匹配。由于 匹配flag_type,因此它会调用该构造函数。这些标志被误解为字符串的大小,当访问字符串末尾的内存时,会导致未定义的行为。

问题不是Visual Studio特有的。我能够在gcc中复制它:http://ideone.com/5DjYiz

可以通过两种方式修复。首先是对参数的明确演绎:

size_t

其次是避免三元表达式中的整数常量:

std::regex re(pattern, static_cast<std::regex::flag_type>(std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0)));

答案 1 :(得分:7)

我没有发现任何提议的解决方案特别引人注目或美观。我想我更喜欢这样的事情:

auto options = std::regex_constants::ECMAScript;
if (caseInsensitive) 
    options |= std::regex_constants::icase;

std::regex re(pattern, options);

如果由于一些误导的原因,你真的坚持一行代码,我会在三元表达式中使用正确类型的值构造对象:

std::regex re(pattern, std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : std::regex_constants::std::regex_option_type{}));

或者,由于ECMAScript是默认值,因此您使用:

std::regex re(pattern, (caseInsensitive ? std::regex_constants::icase : std::regex_constants::ECMAScript));

至少在我看来,第一个显然是优选的。