1

I have a string which is a path taken dynamically from my system. I store it in a string. C:\Users\SXR8036\Downloads\LANE-914.xls

I need to pass this path to a read Excel file function, but it needs the backslashes to be replaced with forward slash.

And I want something like C:/Users/SXR8036/Downloads/LANE-914.xls, i.e., all backslashes replaced with forward ones.

With the String replace method, I am only able to replace with a-z characters, but it shows an error when I replace special characters.

something.replaceAll("[^a-zA-Z0-9]", "/");

I have to pass the String name to read a file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rishav kumar
  • 57
  • 2
  • 11
  • Are you using escape sequence while passing special characters to replaceAll method? – Rehan Haider Mar 12 '16 at 08:15
  • 1
    Why don't you just use `something = something.replace("\\", "/");`? – Jon Skeet Mar 12 '16 at 08:17
  • Java's string replace methods are very poorly named. The choice of `replaceAll` to indicate the regex version makes no sense, and suggests that `replace` only makes a single substitution, which of course it doesn't. Aside: in this case the single-character version `something.replace('\\','/')` would also work. – CupawnTae Mar 12 '16 at 09:03
  • Possibly related: *[How do I write a backslash (\) in a string?](https://stackoverflow.com/questions/18532691/)* and [C# Escape Sequence List](https://stackoverflow.com/questions/323640/can-i-convert-a-c-sharp-string-value-to-an-escaped-string-literal/323664#323664). – Peter Mortensen Jul 12 '23 at 23:46

2 Answers2

3

It's better in this case to use non-regex replace() instead of regex replaceAll(). You don't need regular expressions for this replacement and it complicates things because it needs extra escapes. Backslash is a special character in Java and also in regular expressions, so in Java if you want a straight backslash you have to double it up \\ and if you want a straight backslash in a regular expression in Java you have to quadruple it \\\\.

something = something.replace("\\", "/");

Behind the scenes, replace(String, String) uses regular expression patterns (at least in Oracle JDK) so has some overhead. In your specific case, you can actually use single character replacement, which may be more efficient (not that it probably matters!):

something = something.replace('\\', '/');

If you were to use regular expressions:

something = something.replaceAll("\\\\", "/");

Or:

something = something.replaceAll(Pattern.quote("\\"), "/");
ᴇʟᴇvᴀтᴇ
  • 12,285
  • 4
  • 43
  • 66
  • Very interesting - I didn't know the `CharSequence` version uses regex under the hood - seems like a bizarre choice - wonder why they did that – CupawnTae Mar 12 '16 at 09:11
  • Yeah, it's funny isn't it? You'd think by using that method you'd avoid the overhead of regex, but you don't. It's another reminder why you have to *profile* when you optimize and not make assumptions. – ᴇʟᴇvᴀтᴇ Mar 12 '16 at 09:15
  • Digging around in the source a bit, it makes sense - `Pattern` has special-case code for dealing with literal patterns (`Pattern.LITERAL`), so it won't be doing *full* regex processing, and it makes sense not to duplicate the code/logic in both `String` and `Pattern`, so one of them *should* call the other for the `Pattern.LITERAL` case. `char` version is still better though. – CupawnTae Mar 12 '16 at 09:36
0

To replace backslashes with replaceAll you'll have to escape them properly in the regular expression that you are using.

In your case the correct expression would be:

final String path = "C:\\Users\\SXR8036\\Downloads\\LANE-914.xls";
final String normalizedPath = path.replaceAll("\\\\", "/");

As the backslash itself is the escape character in Java Strings it needs to be escaped twice to work as desired.

In general you can pass very complex regular expressions to String.replaceAll. See the JavaDocs of java.lang.String.replaceAll and especially java.util.regex.Pattern for more information.

dpr
  • 10,591
  • 3
  • 41
  • 71