Escaping double slashes with regular expressions in Java

I have this unit test:

public void testDeEscapeResponse() { final String[] inputs = new String[] {"peque\\\\u0f1o", "peque\\u0f1o"}; final String[] expected = new String[] {"peque\\u0f1o", "peque\\u0f1o"}; for (int i = 0; i < inputs.length; i++) { final String input = inputs[i]; final String actual = QTIResultParser.deEscapeResponse(input); Assert.assertEquals( "deEscapeResponse did not work correctly", expected[i], actual); } } 

I have this method:

 static String deEscapeResponse(String str) { return str.replaceAll("\\\\", "\\"); } 

Unit test error with this error:

 java.lang.StringIndexOutOfBoundsException: String index out of range: 1 at java.lang.String.charAt(String.java:686) at java.util.regex.Matcher.appendReplacement(Matcher.java:703) at java.util.regex.Matcher.replaceAll(Matcher.java:813) at java.lang.String.replaceAll(String.java:2189) at com.acme.MyClass.deEscapeResponse at com.acme.MyClassTest.testDeEscapeResponse 

Why?

+4
source share
3 answers

Use String.replace , which performs a literal replacement, instead of String.replaceAll , which uses regular expressions.

Example:

 "peque\\\\u0f1o".replace("\\\\", "\\") // gives peque\u0f1o 

String.replaceAll accepts a regular expression, so \\\\ interpreted as an expression \\ , which in turn matches one \ . (The replaceable string also has a special treatment for \ , so there is an error there.)

To make String.replaceAll work as you expect, you will need to do

 "peque\\\\u0f1o".replaceAll("\\\\\\\\", "\\\\") 
+4
source

I think the problem is that instead of replace () you are using replaceAll (). replaceAll expects a regular expression in the first field, and you're just trying to match strings.

+2
source

See javadoc for Matcher :

Please note that the backslash (\) and dollar signs ($) in the replacement string may result in different results than if it were considered as a literal replacement string. dollar signs can be considered as references to captured subsequences, as described above, and the backslash is used to exclude alphabetic characters in the replacement string.

Thus, with replaceAll you cannot replace anything with a backslash. So a really crazy solution for your case would be str.replaceAll("\\\\(\\\\)", "$1")

+1
source

All Articles