-1

In Java, the string "\\" represents a single backlash, the first backslash being an escape character. Thus System.out.print("\\") prints \. However if "\\" is given as the replacement argument in method replaceAll, as in "aba".replaceAll("b", "\\"), the following exception is thrown: java.lang.IllegalArgumentException: character to be escaped is missing.

Four slashes does the trick. Thus if one prints "aba".replaceAll("b", "\\\\") the result is a\a. But why is two slashes incorrect? Isn't the first slash the escaping slash, and the second slash the character to be escaped, just like in System.out.print("\\")? Notice that only one escaping slash is sufficient for other replacement strings passed to replaceAll. E.g. printing "aba".replaceAll("b", "\t") results in a a.

Note: I'm using Java SE 9.

Edit: Some the questions suggested as duplicates are not duplicates. Please do not confuse this with the question of why four backslashes are needed in a regex to match a single backslash. This is not the same issue, as the second argument in replaceAll is obviously not a regex. You couldn't specify a replacement String with a regex because ultimately replacement needs to resolve to a literal String.

wedge
  • 1
  • 2
  • 1
    why use `replaceAll` which is using regex when all you need is `replace` – Scary Wombat Jan 19 '18 at 01:43
  • better dupe --> https://stackoverflow.com/questions/18875852/why-string-replaceall-in-java-requires-4-slashes-in-regex-to-actually-r – Ousmane D. Jan 19 '18 at 01:47
  • The issue isn't present with replace. The problem isn't dependent on my simple regex though. You could rework the example with something more interesting that requires replaceAll. – wedge Jan 19 '18 at 02:25

1 Answers1

0

The answer is that replaceAll method takes a regualar expression String which has its own meaning of \ character so you have to escape it twice.

In simple words, reason that "aba".replaceAll("b", "\t") results in a a is that \t is parsed to tabulation before regex, so when regex is parsed it only contains a tabulation.

Jakub Licznerski
  • 1,008
  • 1
  • 17
  • 33
  • 1
    I don't find this answer satisfying, as the second argument to replaceAll is not a regex. However I found at least a partial explanation, and it does have to do with the replacement string encoding more than just a literal String. From Oracle, "An invocation of this method of the form str.replaceAll(regex, repl) yields exactly the same result as the expression _Pattern.compile(regex).matcher(str).replaceAll(repl)_" Then more is explained in Matcher's Javadoc here: [link](https://docs.oracle.com/javase/9/docs/api/java/util/regex/Matcher.html#replaceAll-java.lang.String-) – wedge Jan 19 '18 at 02:33
  • from [here](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#replaceAll(java.lang.String)) "The replacement string may contain references to captured subsequences as in the appendReplacement method.". I think this part is crucial as the replacement String is evaluated for further regex matching. – Jakub Licznerski Jan 19 '18 at 02:39