为什么String.replaceAll()在Java 8中与Java 9的工作方式不同?

Fuy*_*Liu 62 java regex string java-8 java-9

为什么这个代码输出02o2或更高版本中输出?

"o2".replaceAll("([oO])([^[0-9-]])", "0$2")
Run Code Online (Sandbox Code Playgroud)

Kar*_*cki 65

很可能是由于JDK-6609854JDK-8189343报告了负嵌套字符类处理(在您的示例中[^[0-9-]]).此行为在9和10中得到修复,但修复程序未向后移植到8. Java 8的错误解释为:

在Java中,否定也不能适用于任何出现在嵌套[brackets]

因此[^c],如您所料,不匹配"c".

[^[c]]确实匹配"c".不是我所期待的.

[[^c]] 与"c"不匹配

对于范围或属性表达式也是如此 - 如果它们在括号内,则在out级别的否定不会影响它们.

[^a-z] 与...相反 [^[a-z]]

  • 如果不明显 - OP可以通过将`[^ [0-9 - ]]`改为`[^ 0-9-]`来解决这种不一致问题. (18认同)
  • 你无法证明正则表达式与regex101中的字符串不匹配,它不支持字符类联合.在PCRE中,`[^ [0-9 - ]]`匹配一个不是`[`,数字和`-`然后是`]`的字符. (6认同)