为什么在正则表达式中右方括号 "]" 不需要转义?

10

考虑下面这个数组:

new Pattern[] {Pattern.compile("\\["),Pattern.compile("\\]") };

Intellij IDEA提示我\\是多余的,并告诉我将其替换为],例如:

new Pattern[] {Pattern.compile("\\["),Pattern.compile("]") };

为什么在第一个Pattern.compile("\\[")中需要\\,而在第二个中则是多余的?


正则表达式引擎将[视为字符类的开始,因此如果您想表示字面上的[字符,则需要进行转义。假设除非您正在定义字符类,否则它不会将]读作字符类的结尾,因此在这种情况下不需要进行转义。 - khelwood
2个回答

18
如果没有对应的未转义的[,那么]符号在字符类之外不是特殊的正则表达式操作符。只有特殊字符需要转义。一个[在字符类之外是一个特殊的正则表达式操作符(因为它可能标记字符类的起点)。一旦Java正则表达式引擎在模式中看到一个未转义的[,它就知道前面必须有一个]来关闭字符类。无论它是否被转义,对于引擎来说都没有关系。如果表达式中没有开放的[,那么]将被视为纯文字]符号。所以,[abc]将匹配abc,而\[abc]\[abc\]将匹配[abc]字面字符序列。

因此,在任何情况下都应该转义[,而在字符类之外,]不必转义。

当在Java正则表达式中使用字符类时,[]必须被转义,因为它们可能形成交集/减法模式,除非]出现在字符类的开头(即"[a]".replaceAll("[]\\[]", "")返回a)。 其他正则表达式语言

- 在 ICU 和 Onigmo 正则表达式风格中,] 的行为与 Java 正则表达式风格相同。受影响的语言:, , (stringr), ,

- 在Boost、PCRE中,] 不是特殊字符(即在字符类外不需要转义),而在字符类内部它是特殊字符(需要转义,除非它是字符类中的第一个字符)。在所有需要匹配字面上的 ] 字符的地方都转义它不会产生错误。受影响的语言/工具包括://等,(默认基础R TRE和启用"perl=TRUE"的PCRE),

- 在 ECMAScript 中,除了字符类外,] 不是特殊字符,而 [ 是特殊字符。在字符类中,即使它是字符类中的第一个字符,] 必须始终被转义。在字符类内部,[ 不是特殊字符,但如果使用 /u 标志编译正则表达式,则转义它是错误的(在 JavaScript 中)。因此,在这里要小心。受影响的语言有:(它使用 JavaScript)。


7

]只有在用于关闭字符集[...]时才被视为元字符。

如果在]之前没有未关闭和未转义的左方括号[,那么]就是一个简单的字面量,不需要转义(但允许转义,这就是为什么您的IDE会给出“警告”而不是“错误”的原因)。


只有在你想让正则表达式将其视为简单符号而不是元字符(即“关闭”字符集)时,才需要在字符集内部转义]。例如,像"[ab\\]cd]"这样的正则表达式表示ab]cd。但是类似的正则表达式也可以写成[a-d]|]。请注意,最后一个]并不“特殊”,因为它前面没有打开的字符类。因此,它被视为字面量-没有特殊含义的字符,这意味着它不需要转义。

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