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

5
Javadoc对java.util.regex.Pattern的说明中提到\cx代表x所对应的控制字符。因此,我认为Pattern.compile()会拒绝除[@-_]之外的任何字符后面跟着一个\c,但实际上并不是这样的!
正如@tchrist在What is a regular expression for control characters?的答案之一中所评论的那样,根本没有检查范围。我测试了几个来自更高块和星位平面的字符,看起来它仅仅翻转了代码点值的第7个最低位。
那么,这是Javadoc的错误还是实现的错误,还是我理解错了?\cx是Java发明的语法还是其他正则表达式引擎支持的,尤其是Perl?在那里如何处理?

2
你忘记了\c?^?指的是DEL控制字符(0x7F)。 - ikegami
@ikegami 是的,你说得对。我总是忘记0x7F,因为它总是独自呆在角落里。 - user1089451
1个回答

5

以下转义字符在所有版本的Perl中都表现一致:

  • When \c is followed by an ASCII uppercase letter or one of @[\]^_?,

    chr(ord($char) ^ 0x40)

    This provides full coverage of all ASCII control characters (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
    
  • When \c is followed by an ASCII lowercase letter,

    chr(ord($char) ^ 0x60)

    This makes the escape case-insensitive.

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

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

  • ≥5.20,

    • \c 后跟一个空格、ASCII 数字或以下字符之一时: !"#$%&'()*+,-./:;<=>{|}~

      chr(ord($char) ^ 0x40),但会发出警告(更清晰地编写为)。

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

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

  • <5.20,

    • \c 后跟一个空格、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 相同的完全垃圾。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接