Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does String.replaceAll() work differently in Java 8 from Java 9?

Why does this code output 02 in java-8 but o2 in java-9 or above?

"o2".replaceAll("([oO])([^[0-9-]])", "0$2") 
like image 912
Fuyang Liu Avatar asked Mar 01 '19 14:03

Fuyang Liu


People also ask

What is the difference between replaceAll and replace in Java?

The replaceAll() method is similar to the String. replaceFirst() method. The only difference between them is that it replaces the sub-string with the given string for all the occurrences present in the string.

Does replaceAll replace original string?

The replaceAll() method returns a new string with all matches of a pattern replaced by a replacement . The pattern can be a string or a RegExp , and the replacement can be a string or a function to be called for each match. The original string is left unchanged.

What does in replaceAll () mean in Java?

The replaceAll() method replaces each substring of this string that matches the given regular expression with the given replacement.

What does replaceAll return in Java?

The Java String replaceAll() returns a string after it replaces each substring of that matches the given regular expression with the given replacement.


Video Answer


1 Answers

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]]

like image 185
Karol Dowbecki Avatar answered Oct 11 '22 03:10

Karol Dowbecki