我最近创建了C++ 11 std::regex的实现,该实现通过了许多一致性测试。由于C++ 11 std::regex语法和语义是从ECMAScript 5.1派生的,所以我认为我将针对浏览器运行相同的测试,以检查行为的匹配程度。

我在处理无效的转义序列时发现了一些奇怪的差异。

/* As expected, matching the standard: */
/\,/.exec(",") -> [","]

/* Err... this should throw, it doesn't match any ECMAScript production:
   IdentityEscape := SourceCharacter but not IdentifierPart (ES 5.1)
                     SourceCharacter but not UnicodeIDContinue (ES 6.0) */
/\z/.exec("z") -> ["z"] (Chrome & Firefox!)

/* It even works for characters that have a defined meaning: */
/\u/.exec("u") -> ["u"] (Chrome)
                  null (Firefox)

/* Errr...! This is creepiest, it matches a backslash!!! */
/\c/.exec("\\c") -> ["\c"] (Chrome & Firefox!)

这些已知的一致性问题是Chrome和Firefox中的,还是它们符合某些先前/将来的ECMAScript行为?

最佳答案

标题为ECMAScript IdentityEscape is ambiguous的规范存在问题。此处的讨论表明浏览器正在使用此规则解决此问题:



确实,我可以确认MSDN列出了此修复程序。

请记住,规范指出:



因此,那里的那一行意味着\,\z\u可以在那里匹配。但不是\c

当然,\u仅在此处不匹配时才匹配:



特别:



但是为什么要c?可能是因为它很特殊(他们可能已经忘记了它们被c ControlLetter保护)。根据Regex101.com:



Regex101.com还说明了如何解析\c:



(我怀疑Firefox可能会类似地对待\u。)

...除非您使用的是u修饰符。在这种情况下,请忘记所有内容,因为\u\c本身就是错误。

在PCRE中(其中\u\c具有相同的含义),使用和不使用u修饰符,这些正则表达式都是错误。至少在我看来,这种行为是“正确的”。

底线:不必要的转义定义不明确,应为错误。
避免他们。

10-06 04:27
查看更多