I have to replace \\ with \ in Java. The code I am using is
System.out.println( (MyConstants.LOCATION_PATH + File.separator + myObject.getStLocation() ).replaceAll("\\\\", "\\") );
But I don't know why it is throwing StringIndexOutOfBoundsException.
It says String index out of range: 1
What could be the reason? I guess it is because the first argument replaceAll accepts a pattern. What could be the possible solution?
Stacktrace
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(String.java:558)
at java.util.regex.Matcher.appendReplacement(Matcher.java:696)
at java.util.regex.Matcher.replaceAll(Matcher.java:806)
at java.lang.String.replaceAll(String.java:2000)
Answer Found
asalamon74 posted the code I required, but I don't know why he deleted it. In any case here it is.
There is a bug already filed in Java's bug database. (Thanks for this reference, asalamon.)
yourString.replaceAll("\\\\", "\\\\");
Amazingly, both search and replace string are the same :) but still it does what I require.
Use String.replace instead of replaceAll to avoid it using a regex:
String original = MyConstants.LOCATION_PATH + File.seperator
+ myObject.getStLocation();
System.out.println(original.replace("\\\\", "\\"));
Personally I wouldn't do it this way though - I'd create MyConstants.LOCATION_PATH_FILE as a File and then you could write:
File location = new File(MyConstants.LOCATION_PATH_FILE,
myObject.getStLocation());
which will do the right thing automatically.
Well, i tried
String test = "just a \\ test with some \\\\ and others \\\\ or \\ so";
String result = test.replaceAll("\\\\", "\\\\");
System.out.println(test);
System.out.println(result);
System.out.println(test.equals(result));
and got, as expected
just a \ test with some \\ and others \\ or \ so
just a \ test with some \\ and others \\ or \ so
true
What you really need is
string.replaceAll("\\\\\\\\", "\\\\");
to get
just a \ test with some \\ and others \\ or \ so
just a \ test with some \ and others \ or \ so
false
You want to find: \\ (2 slashes)
which needs to be escaped in the regex: \\\\ (4 slashes)
and escaped in Java: "\\\\\\\\" (8 slashes)
same for the replacement...
For the regex, if you want to change \ to \\, you should do this:
if (str.indexOf('\\') > -1)
str = str.replaceAll("\\\\", "\\\\\\\\");
str = "\"" + str + "\"";
Where \\\\ means \ and \\\\\\\\ means \\.
File.seperator is already escaped as is any string object so you are escaping them twice.
You only need to escape values that you are entering as a string literal.
The best way is :
str.replace(**'**\\**'**, **'**/**'**); //with char method not String
Try this
cadena.replaceAll("\\\\","\\\\\\\\")
I suspect the problem is that replaceAll() uses regexps and the backslash is an escape character in regexps as well as in Java - it might be necessary to double the number of backslashes.
In general you should always post the full stack trace of exceptions, it is much easier to diagnose the problem that way.
I believe what you need to do is:
System.out.println( (MyConstants.LOCATION_PATH + File.separator + myObject.getStLocation() ).replaceAll("\\\\\\\\", "\\\\") );
The regular expression String is actually four backslashes, which is a regular expression that matches two backslashes.
The replacement String has to be four slashes as per Java documentation, from:
http://java.sun.com/javase/6/docs/api/java/util/regex/Matcher.html#replaceAll(java.lang.String)
Note that backslashes () and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are used to escape literal characters in the replacement string.
final StringBuilder result = new StringBuilder();
final StringCharacterIterator iterator = new StringCharacterIterator(str);
char character = iterator.current();
while (character != CharacterIterator.DONE )
{
if (character == '\\\\') {
result.append("\\");
}
else {
result.append(character);
}
character = iterator.next();
}
System.out.print(result);
Related
I'm solving this problem in my own way. I'm trying to split the file path into Drive, folders, and file name, all into an array.
Complete class. (Github)
The problem:
String regex = "\\";
String [] divisions = path.split (regex);
This gives me an java.util.regex.PatternSyntaxException. I looked up the wiki and found [\b]
String regex = "[\b]";
String [] divisions = path.split (regex);
This doesn't work. It doesn't throw an exception, nor does it split my file path based on backspace.
Input:
► Enter path --
C:\User\Admin\NekedGaben.jpg
Output:
→ Path = C:\User\Admin\NekedGaben.jpg
→ File name = C:\User\Admin\NekedGaben
→ Extension = .jpg
My questions:
Why does "\\" throw an exception, while "[\b]" doesn't?
Why doesn't the split() split the Path string?
You should use double escaping in Java regex, i.e.:
String regex = "\\\\";
Or use static Pattern.quote(String) method:
String regex = Pattern.quote("\\");
Because \b is a single character, the compiler knows it, they're friends.
However backslash (\) is represented by \\ in Java, and \ is invalid regex, in order to escape it, you should use:
\\\\
↓ ↓
escaping
Solution:
Escape it as shown above
Don't escape, let Pattern#quote handle this for you
Hi we have a string like "ami\\303\\261o". we want to replace \\ with \.
We have tried the following:
replace("\\", "\")
replaceAll("\\", "\")
But we didn't get proper output.
For use in a Java regex, you need to escape the backslashes twice:
resultString = subjectString.replaceAll("\\\\\\\\", "\\\\");
In a regex, \\ means "a literal backslash".
In a Java string, "\\" encodes a single backslash.
So, a Java string that describes a regex that matches a single backslash is "\\\\"
And if you want to match two backslashes, it's "\\\\\\\\", accordingly.
You must keep backslash escaping in mind. Use
public class so {
public static void main(String[] args) {
String s = "ami\\\\303\\\\261o";
System.out.println(s);
s = s.replace("\\\\", "\\");
System.out.println(s);
}
};
Each backslash escapes the following backslash and resolves to the two literal strings \\ and \
Also keep in mind, String.replace returns the modified string and keeps the original string intact.
No need of regex here. Escape the slashes and use replace()
someString.replace('\\\\', '\\');
Thats because the \\ inside your input String get internally replaced by \ because of the Java Escape Character.
That means that if you output your String without performing any regex on it, it would look like this: "ami\303\261o".
Generally you should remember to escape every escape-character with itself:
\ -> escaped = \\
\\ -> escaped = \\\\
\\\ -> escaped = \\\\\\
...and so on
Try below code
String val = "ami\\303\\261o";
val =val.replaceAll("\\\\", "\\\\");
System.out.println(val);
Outpout would be
ami\303\261o
A Fiddle is created here check it out
Java Running Example
I am trying to replace '\\'with '/' in java(Android) and this does not seem to work!
String rawPath = filePath.replace("\\\\", "/");
What is wrong with this ? I have escaped "\" and tried escaping '/' but to no use. Nothing happens to the original string.
filePath = abc\\xyz(not after escaping two \\, the original string is with two \\)
rawPath = abc \ xyz
expected = abc/xyz
Whats the correct way of doing this? (Another Windows file to Android path conversion prob)
When using String.replace(String, String) the backslash doesn't need to be escaped twice (thats when using replaceAll - it deals with regex). So:
String rawPath = filePath.replace("\\", "/");
Or using char version:
String rawPath = filePath.replace('\\', '/');
You do not need the quad-druple escape,
\\\\
, just simply
\\
.
escape with single slash should be enough. Following is working fine for me.
String rawPath = filePath.replace("\\", "/");
public static void main(String[] args) {
String s = "foo\\\\bar";
System.out.println(s);
System.out.println(s.replace("\\\\", "/"));
}
will print
foo\\bar
foo/bar
If you want to replace a sequence of 2 backslashes in your original string with a single forward slash, this should work:
String filePath = "abc\\\\xyz";
String rawPath = filePath.replace("\\\\", "/");
System.out.println(filePath);
System.out.println(rawPath);
outputs:
abc\\xyz
abc/xyz
Do you really have two backslashes in the String in the first place? That only appears in Java source code. At runtime there will only be one backslash. So the task reduces to changing backslashes to forward slashes (why?). For which you need a regex if you are using replaceAll(), which would require four of them: two for the compiler, and two for the regex, but you aren't using that, you are using replace(), which isn't a regex, so you only need two, one for the compiler and one for itself.
Why are you doing this? It is never necessary to use a backslash in a File path in Java at all, and it is also never necessary to translate them to / unless you are doing URL-like things with them, in which case there are File.toURI() methods and URI and URL classes for that.
Here is a very small method to get the desktop path and show you how to replace them in the return statement.
public static String getDesktopPath() {
String desktopPath = System.getProperty("user.home") + "/Desktop";
return desktopPath.replace("\\", "/");
}
I have a String str=p2\7\2010 I want to check and replace if str.contains("\") then replace it into this("\\\\") instead of \. i am unable to do this in Java please give your little effort.
use String.replace():
if (str.contains("\\")) {
str = str.replace("\\", "\\\\");
}
You can also use String.replaceAll(), but it uses regular expressions and so is slower in such trivial case.
UPDATE:
Implementation of String.replace() is based on regular expressions as well, but compiled in Pattern.LITERAL mode.
str.contains("\"") matches string that have a " in them.
What you probably want is str.replaceAll("\\", "\\\\")
Additionally; for checking if it contains a \ you'd need str.contains("\\"), since the \ is a special character it has to be escaped.
Try this,
String newString = oldString.replace("/", "//");
or try pattern method,
Pattern pattern = Pattern.compile("/");
Matcher matcher = pattern.matcher("abc/xyz");
String output = matcher.replaceAll("//");
I have a path called $SERVER/public_html/ab1/ab2/.
I want to change it so that instead of $SERVER it just replaces it with my user directory. So I do
path = path.replaceFirst("\\$SERVER", System.getProperty("user.dir"));
but when I run it, it removes my \ in the new string.
F:Programming ProjectsJava Project/public_html/ab1/ab2/
Pattern has a String quote(String) function that will help you for the first string and Matcher has String quoteReplacement(String) for the second:
path = path.replaceFirst(java.util.regex.Pattern.quote("$SERVER"), java.util.regex.Matcher.quoteReplacement(System.getProperty("user.dir")));
edit: the reason you have to escape anything is because the second string has the semantics of Matcher.appendReplacement which treats backslashes and dollars as escape next char and insert captured group resp.
from the doc:
Note that backslashes () and dollar
signs ($) in the replacement string
may cause the results to be different
than if it were being treated as a
literal replacement string. Dollar
signs may be treated as references to
captured subsequences as described
above, and backslashes are used to
escape literal characters in the
replacement string.
a more obvious solution is (be careful of the needed escaped with that backslash)
path = path.replaceFirst("\\$SERVER", System.getProperty("user.dir").replaceAll("\\\\","\\\\\\\\"));
Yea you are completly right. I am trying to figure out why it is happening so.
But at the moment the only think I can suggest is to go with such a solution.
public class RegExTest
{
public static void main(String[] args)
{
String path = "$SERVER/public_html/ab1/ab2";
System.out.println("path before="+path);
String user = System.getProperty("user.dir");
System.out.println("user="+user);
System.out.println("replaceFirst using user="+path.replaceFirst("\\$SERVER", user));
path = path.replaceFirst("\\$SERVER", "");
path = user +path;
System.out.println("path after="+path);
}
}
EDIT: ..Why it does that?
From what I see in the code of the method line 701 to 708 they must do it. They just skip them. As to the reason why they do it, I still am not sure.
EDIT2:
OK reading the doc for the method answers it all. They do it so they can interpret accordingly special characters. Thus when reading the replacement they spot a slash the algorithm assumes it can be a part of special character and in result skips it.
if (nextChar == '\\') {
cursor++;
nextChar = replacement.charAt(cursor);
result.append(nextChar);
cursor++;
} else if (nextChar == '$') {
// Skip past $
cursor++;
Ok so in Windows the default slashes look like so '\' whereas on *nix the slashes look like so '/' . The simplest way to get through this problem is to invoke the replace function with the following parameters '\\' and '/' . That way you path will have its slashes all facing the same way.