Why does String.replaceAll() work differently in Java 8 from Java 9?
JavaRegexStringJava 8Java 9Java Problem Overview
Why does this code output 02
in [tag:java-8] but o2
in [tag:java-9] or above?
"o2".replaceAll("([oO])([^[0-9-]])", "0$2")
Java Solutions
Solution 1 - Java
Most likely due to JDK-6609854 and JDK-8189343 which reported negative nested character classes handling (in your example [^[0-9-]]
). This behavior was fixed in 9 and 10, but fix was not backported to 8. The bug for Java 8 is explained as:
> In Java, the negation does not apply to anything appearing in
> nested [brackets]
>
> So [^c]
does not match "c", as you would expect.
>
> [^[c]]
does match "c". Not what I would expect.
>
> [[^c]]
does not match "c"
>
> The same holds true for ranges or property expressions - if they're
> inside brackets, a negation at an out level does not affect them.
>
> [^a-z]
is opposite from [^[a-z]]