正则表达式

时间:2017-02-24 20:17:52

标签: javascript regex standards pcre

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

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

[\11]

以下是核心规范的相关部分:

  • 21.2.2.19 ClassEscape

      

    生产ClassEscape :: DecimalEscape的计算结果如下:

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

      

    生产DecimalEscape :: DecimalIntegerLiteral的计算结果如下:

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

      “DecimalIntegerLiteral的MV”的定义见11.8.3。

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

在网络浏览器的其他功能中还提到了ClassEscape

  • B.1.4.1 Pattern Semantics

      

    ClassEscape(21.2.2.19)包括以下附加评估规则:

         

    生产ClassEscape :: DecimalEscape但仅当...评估如下:

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

我的主要问题是我觉得规则DecimalEscape只有在识别出0(然后它返回U+0000)时才产生一个字符,否则它返回一个整数,但我不能在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 :(得分:1)

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

返回true,因为转义的整数被视为八进制表示法中的数字(基数为8)

显然,当你使用8和9不能在base 8中使用时,不可能再有可能。在这种情况下,反斜杠就会被忽略。

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

返回false,因为\10 (基础8)提供8 (基础10)

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

将返回true

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