考虑下面这个数组:
new Pattern[] {Pattern.compile("\\["),Pattern.compile("\\]") };
Intellij IDEA提示我\\
是多余的,并告诉我将其替换为]
,例如:
new Pattern[] {Pattern.compile("\\["),Pattern.compile("]") };
为什么在第一个Pattern.compile("\\[")
中需要\\
,而在第二个中则是多余的?
考虑下面这个数组:
new Pattern[] {Pattern.compile("\\["),Pattern.compile("\\]") };
Intellij IDEA提示我\\
是多余的,并告诉我将其替换为]
,例如:
new Pattern[] {Pattern.compile("\\["),Pattern.compile("]") };
为什么在第一个Pattern.compile("\\[")
中需要\\
,而在第二个中则是多余的?
[
,那么]
符号在字符类之外不是特殊的正则表达式操作符。只有特殊字符需要转义。一个[
在字符类之外是一个特殊的正则表达式操作符(因为它可能标记字符类的起点)。一旦Java正则表达式引擎在模式中看到一个未转义的[
,它就知道前面必须有一个]
来关闭字符类。无论它是否被转义,对于引擎来说都没有关系。如果表达式中没有开放的[
,那么]
将被视为纯文字]
符号。所以,[abc]
将匹配a
、b
或c
,而\[abc]
或\[abc\]
将匹配[abc]
字面字符序列。
因此,在任何情况下都应该转义[
,而在字符类之外,]
不必转义。
[
和]
必须被转义,因为它们可能形成交集/减法模式,除非]
出现在字符类的开头(即"[a]".replaceAll("[]\\[]", "")
返回a
)。
其他正则表达式语言
icu onigmo - 在 ICU 和 Onigmo 正则表达式风格中,]
的行为与 Java 正则表达式风格相同。受影响的语言:swift, ruby, r (stringr
), kotlin, groovy。
pcre boost .net re2 python posix - 在Boost、PCRE中,]
不是特殊字符(即在字符类外不需要转义),而在字符类内部它是特殊字符(需要转义,除非它是字符类中的第一个字符)。在所有需要匹配字面上的 ]
字符的地方都转义它不会产生错误。受影响的语言/工具包括:php,perl,c#/vb.net/等,python,sed,grep,awk,elixir,r(默认基础R TRE和启用"perl=TRUE"
的PCRE),tcl,google-sheets。
ECMAScript - 在 ECMAScript 中,除了字符类外,]
不是特殊字符,而 [
是特殊字符。在字符类中,即使它是字符类中的第一个字符,]
必须始终被转义。在字符类内部,[
不是特殊字符,但如果使用 /u
标志编译正则表达式,则转义它是错误的(在 JavaScript 中)。因此,在这里要小心。受影响的语言有:JavaScript、Dart、C++、VBA、Google Apps Script(它使用 JavaScript)。
]
只有在用于关闭字符集[...]
时才被视为元字符。
如果在]
之前没有未关闭和未转义的左方括号[
,那么]
就是一个简单的字面量,不需要转义(但允许转义,这就是为什么您的IDE会给出“警告”而不是“错误”的原因)。
]
。例如,像"[ab\\]cd]"
这样的正则表达式表示a
或b
或]
或c
或d
。但是类似的正则表达式也可以写成[a-d]|]
。请注意,最后一个]
并不“特殊”,因为它前面没有打开的字符类。因此,它被视为字面量-没有特殊含义的字符,这意味着它不需要转义。
[
视为字符类的开始,因此如果您想表示字面上的[
字符,则需要进行转义。假设除非您正在定义字符类,否则它不会将]
读作字符类的结尾,因此在这种情况下不需要进行转义。 - khelwood