【发布时间】:2014-06-22 11:47:43
【问题描述】:
注意:当我说 正则表达式 [\0] 时,我的意思是正则表达式 [\0](不包含在 C 风格的字符串中,即 @987654327 @)。如果我没有在它周围加上引号,它就不是 C 风格的字符串,并且反斜杠不应被解释为转义 C 风格的字符串。
受this question and my investigation的启发,我在clang 3.4中尝试了以下代码:
#include <regex>
#include <string>
int main()
{
std::string input = "foobar";
std::regex regex("[^\\0]*"); // Note, this is "\\0", not "\0"!
return std::regex_match(input, regex);
}
显然,clang 不喜欢这样,因为它会抛出:
std::__1::regex_error: 表达式包含无效的转义字符或尾随转义。
这似乎是 [^\0] 部分(将其更改为 [^\n] 或类似的工作正常)。它似乎是一个无效的转义字符。我想澄清一下,我不是在谈论 '\0' 字符(空字符)或 '\n' 字符(换行符)。 在C风格的字符串中,我说的是"\\0"(一个包含反斜杠零的字符串)和"\\n"(一个包含反斜杠n的字符串)。 "\\n" 似乎被正则表达式引擎转换为 "\n",但它在 "\\0" 上卡住了。
C++11 标准在第 28.13 节 [re.grammar] 中说:
使用 ECMAScript 标志构造的
basic_regex对象所识别的正则表达式语法是由 ECMA-262 指定的,除非下面指定。
我不是 ECMA-262 方面的专家,但 I tried the regular expression on JSFiddle 它在 JavaScript 领域运行良好。
所以现在我想知道正则表达式 [^\0] 在 ECMA-262 中是否有效并且 C++11 标准删除了对它的支持(在 ... except as specified below. 之后的内容中)。
问题:\0(不是空字符;在字符串文字中这将是"\\0")转义序列在 C++11 正则表达式中是否合法?它在 ECMA-262 中是否合法(或者浏览器 JS VM 是否“过于”宽松)?不同行为的原因/理由是什么?
【问题讨论】:
-
@user3590396:当然,我可以写
"[^" + std::string(1, '\0') + "]*"并完成它,但我不是在问 如何 来匹配这个,我是在问 为什么存在差异,因为 C++11 正则表达式基于 ECMA 的正则表达式。 -
我认为这是因为 ECMA 正则表达式使用更高阶的字符串,并且在将其输入字符串而不是将其编译为字符串终止字符时会转义 \0,而在 c 字符串中它会终止字符串,这就是为什么你需要做一些工作来插入它。
-
@Cornstalks:我已将其推送到 llvm 错误跟踪器(我个人认为 gnu 的行为是正确的)。 llvm.org/bugs/show_bug.cgi?id=19678
-
在 libc++ 修订版 209307 中修复
标签: javascript c++ regex c++11 ecma262