微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用扩展 POSIX 语法的 C 正则表达式与 C++ 正则表达式中的不同行为

如何解决使用扩展 POSIX 语法的 C 正则表达式与 C++ 正则表达式中的不同行为

在使用 C POSIX 正则表达式库和 C++ 标准库实现时,我看到了不同的结果。这是我的代码

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);
cout << "C: " << result << endl;

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

C 部分成功匹配空格,但 C++ 部分抛出此错误

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

我知道字符串文字被转义意味着模式匹配中使用的实际正则表达式应该是\s。我也只在使用 POSIX 扩展语法时看到这个问题。在C++版本中,如果我在构造正则表达式时不指定POSIX扩展语法,则认为ECMAScript语法,可以正确解析。

这里发生了什么?

解决方法

regex_constants::extended 触发不支持 POSIX ERE regex syntaxshorthand character classes。请注意,C regex.h 模块支持 \s 作为非标准扩展。

要匹配启用了 regex_constants::extended 的 POSIX ERE 风格中的任何空格,您需要使用 string pattern = "[[:space:]]"

但是,您应该只依赖于 default ECMAScript flavor,并使用

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

在 Posix RE 中

任何以转义开头的普通字符的效果是不确定的。

(来自boost docs

9.4.2 ERE 普通字符

普通字符是与自身匹配的 ERE。普通字符是受支持字符集中的任何字符,但 ERE 特殊字符中列出的 ERE 特殊字符除外。以未转义 ( '\' ) 开头的普通字符的解释未定义,除非在括号表达式的上下文中(请参阅 ERE 括号表达式)。

(来自posix docs

类似的措辞适用于 BRE。

因此两者都符合 posix,因为您的 RE 实际上未定义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。