views:

1441

answers:

4

I'm trying to convert "\something\" into "\\something\\" using replaceAll, but I keep getting all kinds of errors. I thought this was the solution:

theString.replaceAll("\\", "\\\\");

But this gives: Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 1

+1  A: 

You'll need to escape the (escaped) backslash in the first argument as it is a regular expression. Replacement (2nd argument - see Matcher#replaceAll(String)) also has it's special meaning of backslashes, so you'll have to replace those to:

theString.replaceAll("\\\\", "\\\\\\\\");
sfussenegger
This gives me the same string as I started with.
Frank Groeneveld
Frank is right, it does. See javadoc of Matcher#replaceAll(String): Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. So backslashes will also have to be escaped in the second argument
sfussenegger
+1  A: 

Yes... by the time the regex compiler sees the pattern you've given it, it sees only a single backslash (since Java's lexer has turned the double backwhack into a single one). You need to replace "\\\\" with "\\\\", believe it or not! Java really needs a good raw string syntax.

Jonathan Feinberg
+5  A: 

To avoid this sort of trouble, you can use replace (which takes a plain string) instead of replaceAll (which takes a regular expression). You will still need to escape backslashes, but not in the wild ways required with regular expressions.

Fabian Steeg
+7  A: 

Something says me that you're trying to use Windows-like file system paths. If this is true, then it may be useful to know that you can also just use the forward slash as path separator in windows.

As to your actual problem: the \ is an escape character in both the String and in regex. You need to re-escape it as well:

string.replaceAll("\\\\", "\\\\\\\\");

But you don't necessarily need regex for this, simply because you want an exact character-by-character replace and you don't need patterns here. So String#replace() would suffice:

string.replace("\\", "\\\\");
BalusC
Actually, it is used in a JavaScript AST that should be converted back to source. Your solution works. Thanks!
Frank Groeneveld