我最近创建了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
修饰符,这些正则表达式都是错误。至少在我看来,这种行为是“正确的”。
底线:不必要的转义定义不明确,应为错误。
避免他们。