Java正则表达式\cx(控制字符)

Java regular expression \cx (control characters)

Javadoc for java.util.regex.Pattern\cx表示x对应的控制字符。所以我认为 Pattern.compile() 会拒绝 \c 后跟 [@-_] 以外的任何字符,但它不会!

正如@tchrist 对 What is a regular expression for control characters? 的一个答案所评论的那样,根本没有检查范围。我测试了来自更高方块和星体层的几个字符,看起来它只是翻转了代码点值的第 7 个最低位。

那么这是 Javadoc bug 还是实现 bug 还是我误解了什么? \cx 是 Java 发明的语法还是其他正则表达式引擎(尤其是 Perl)支持它?那里是怎么处理的?

对于以下转义,所有版本的 Perl 行为相同:

  • \c后跟一个ASCII大写字母或@[\]^_?

    之一时

    chr(ord($char) ^ 0x40)

    这提供了对所有 ASCII 控制字符的全面覆盖 (0x00..0x1F, 0x7F).

    \c@ === \x00
    \cA === \x01
    ...
    \cZ === \x1A
    \c[ === \x1B
    \c\ === \x1C   # Sometimes \c\ is needed.
    \c] === \x1D
    \c^ === \x1E
    \c_ === \x1F
    \c? === \x7F
    
  • \c后跟一个ASCII小写字母时,

    chr(ord($char) ^ 0x60)

    这使得转义不区分大小写。

    \ca === \cA === \x01
    ...
    \cz === \cZ === \x1A
    

没有其他序列有意义,但错误检查仅在 Perl 5.20 中引入。

  • ≥5.20,

    • \c 后跟 space、ASCII 数字或 !"#$%&'()*+,-./:;<=>{|}~

      之一时

      chr(ord($char) ^ 0x40),但警告 (is more clearly written simply as)。

    • \c后跟一个ASCII控制字符(0x00..0x1F,0x7F)或非ASCII字符( ≥0x80),

      致命错误 Character following "\c" must be printable ASCII.

  • <5.20,

    • \c 后跟 space、ASCII 数字、!"#$%&'()*+,-./:;<=>{|}~ 之一或 ASCII 控制字符(0x00 ..0x1F, 0x7F),

      chr(ord($char) ^ 0x40)

    • \c后跟字符≥0x100,

      垃圾总数(chr(ord(substr(encode_utf8($char, 0, 1)) ^ 0x40) . encode_utf8($char, 1))。

    • \c后跟字符0x80..0xFF,

      根据字符串的内部存储格式,产生 chr(ord($char) ^ 0x40) 或与字符 ≥0x100.

    • 相同的总垃圾