2017-02-24 5 views
0

根据ECMAScript标准,有人可以解释字符类中的十进制转义的语义吗?正则表达式中的字符类中的十进制转义

例如,以下模式意味着什么?它应该抛出一个语法错误?

[\11] 

以下是核心规范的相关章节:

  • 21.2.2.19 ClassEscape

    生产ClassEscape :: DecimalEscape计算如下:

    1. 评估DecimalEscape到获取EscapeValue E.
    2. 如果E不是一个字符,则抛出一个SyntaxError异常。
    3. 让ch成为E的角色。
    4. 返回包含字符ch的单元素CharSet。
  • 21.2.2.11 DecimalEscape

    生产DecimalEscape :: DecimalIntegerLiteral计算如下:

    1. 让我成为DecimalIntegerLiteral的MV。
    2. 如果i为零,则返回由字符U + 0000(NULL)组成的EscapeValue。
    3. 返回由整数i组成的EscapeValue。

    “DecimalIntegerLiteral的MV”的定义在11.8.3中。


    • 如果\后跟一个十进制数n,其第一位数字不为0,则该转义序列被认为是一个反向引用。如果n大于整个正则表达式中左侧捕获括号的总数,则为错误。 \ 0表示字符,不能跟随一个十进制数字。

也有参加附加功能ClassEscape网络浏览器的一提:

  • B.1.4.1 Pattern Semantics

    ClassEscape(21.2.2。19)包含以下附加评估规则:

    生产ClassEscape :: DecimalEscapebut仅当...计算如下:

    1. 评估DecimalEscape以获得EscapeValue E.
    2. 断言:E是一个字符。
    3. 让ch成为E的角色。
    4. 返回包含字符ch的单元素CharSet。

我的主要问题是,我觉得,如果它承认0(然后返回U+0000)规则DecimalEscape只产生一个字符,否则它返回一个整数,但我无法得到在使用Firefox中的Javascript控制台进行测试时出现语法错误。

这里有一些结果我发现:

// This is the only one I understand: 
/[\0]/.test("\x00") // true 

// Now it gets strange 
/[\1]/.test("\x01") // true 
/[\2]/.test("\x02") // true 
/[\3]/.test("\x03") // true 
/[\4]/.test("\x04") // true 
/[\5]/.test("\x05") // true 
/[\6]/.test("\x06") // true 
/[\7]/.test("\x07") // true 
/[\8]/.test("\x08") // false 
/[\9]/.test("\x09") // false 
/[\10]/.test("\x0a") // false 
/[\11]/.test("\x0b") // false 

// This is not interpreted as `\1` and `0` 
/[\10]/.test("0") // false 

// Also, it's not a backreference 
/((((((((((a))))))))))[\10]/.test("aa") // false 

为什么它返回true高达7,然后false?这不应该与八进制相关。我希望澄清一些情况。

回答

1
/[\0]/.test("\x00") 
... 
/[\7]/.test("\x07") 

返回true因为逸出的整数被视为数字八进制(基座8)

显然,当使用基数8中没有使用的8和9时,它不是不可能的。在这种情况下,简单地忽略反斜杠。

/[\10]/.test("\x0a") 
/[\11]/.test("\x0b") 

因为\10(基座8)返回false给出8 (基体10)

/[\10]/.test("\x08") 
/[\11]/.test("\x09") 

将返回true

此行为是浏览器附加功能(兼容性)的一部分。部分B.1.2 String Literals增加了LegacyOctalEscapeSequence生产规则EscapeSequence。此规则定义了八进制转义\0高达\377代码单位从0到255.

+0

谢谢,似乎Firefox和Node.js都将_decimalEscape_解释为八进制。它进入'/ [\ 377] /。test(“\ u00ff”)',但是然后'/ [\ 400] /。test(“\ u0100”)是错误的。目前,这只是一个观察,你能否提供指定此行为的权威来源的链接? – Demurgos

+0

发现它:它是浏览器添加的一部分(B.1.2),我编辑了你的答案以包含它。 – Demurgos