如何处理无效的正则表达式转义?

时间:2016-11-18 10:10:40

标签: javascript regex google-chrome firefox ecmascript-6

我最近创建了一个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行为?

1 个答案:

答案 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修饰符的错误。至少在我看来,这种行为是“正确的”。

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