我最近创建了一个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行为?
答案 0 :(得分:1)
标题为ECMAScript IdentityEscape is ambiguous的规格存在问题。那里的讨论表明浏览器正在使用此规则来解决问题:
IdentityEscape :: SourceCharacter but not c
确实,我可以确认MSDN列出了修复程序。
请记住规范说明:
SourceCharacter :: any Unicode code unit
因此,那里的行意味着\,
,\z
和\u
可以匹配。但不是\c
。
\u
只有在匹配时才会匹配:
CharacterEscape :: ControlEscape c ControlLetter HexEscapeSequence UnicodeEscapeSequence OctalEscapeSequence IdentityEscape
具体做法是:
UnicodeEscapeSequence :: u HexDigit HexDigit HexDigit HexDigit
但为什么c
?可能是因为它是特殊的(他们可能已经忘记了它们被c ControlLetter
覆盖)。根据Regex101.com:
\cY
匹配通常与Control + A通过Control + Z:\ x01到\ x1A关联的ASCII字符。
Regex101.com还解释了如何解析\c
:
\c
字面匹配字符\c
(区分大小写)
(我怀疑Firefox可能会同样对待\u
。)
...除非您使用u
修饰符。在这种情况下,请忘记所有内容,因为\u
和\c
都是错误。
在PCRE中,(\u
和\c
具有相同的含义),这些正则表达式是带有和不带u
修饰符的错误。至少在我看来,这种行为是“正确的”。
底线:不必要的转义定义不明确,应该是错误。
避免他们。