请注意,这与不是是关于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或支撑。为什么呢?
答案 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));
至少在我看来,第一个显然是优选的。