Escaping '\' for use with Java replaceAll method - java

I am getting some weird results when using the replaceAll method of the String class.
The string query contains the following: #cm:name:"hello"
If I say query.replaceAll(":", "\\:");
I would expect the following result: #cm\:name\:"hello"
Instead I get: #cm:name:"hello". The original content.

Don't use replaceAll(..) for non-regex replaces. Use replace(..) instead.
Then, be sure to have:
query = query.replace(":", "\\:");
because String is immutable - i.e. if you just call the method without assigning the result, you get nothing - the internal state of the object won't change.

There are two simple rules.
The Java compiler requires two blackslashes to represent a single backslash in a string literal .
Regular expressions require two backslashes to represent a single backslash in a regular expression.
So if you want a string literal to contain a regular expression single backslash you have to write four.

The escape sequence for \ is \\. So, you'd write this:
query.replaceAll(":", "\\:");

Escape the slash
query.replaceAll(":","\\:");

Related

What all characters can be used as String Delimiters in Java?

I am trying break a String in various pieces using delimiter(":").
String sepIds[]=ids.split(":");
It is working fine. But when I replace ":" with " * " and use " * " as delimiter, it doesn't work.
String sepIds[]=ids.split("*"); //doesn't work
It just hangs up there, and doesn't execute further.
What mistake I am making here?
String#split takes a regular expression as parameter. In regex some chars have special meanings so they need to be escaped, for example:
"foo*bar".split("\\*")
the result will be as you expect:
[foo, bar]
You could also use the method Pattern#quote to simplify the task.
"foo*bar".split(Pattern.quote("*"))
String.split expects a regular expression argument. * has got a meaning in regex. So if you want to use them then you need to escape them like this:
String sepIds[]=ids.split("\\*");
The argument of .split() is a regular expression, not a string literal. Therefore you need to escape * since it is a special regex character. Write:
ids.split("\\*");
This is how you would split agaisnt one or more spaces:
ids.split("\\s+");
Note that Guava has Splitter which is very, very fast and can split against literals:
Splitter.on('*').split(ids);
'*' and '.' are special characters you have to blackshlash it.
String sepIds[]=ids.split("\\*");
To read more about java patterns please visit that page.
That is expected behaviour. The documentation for the String split function says that the input string is treated as a regular expression (with a link explaining how that works). As Germann points out, '*' is a special character in regular expressions.
Java's String.split() uses regular expressions to split up the string (unlike similar functions in C# or python). * is a special character in regular expressions and you need to escape it with a \ (backslash). So you should use instead:
String sepIds[]=ids.split("\\*");
You can find more information on regular expressions anywhere on the internet a quite complete list of special characters supported by java should be here: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

nextLink1.replace("""), Making " act differently

nextLink1.replace(""",()), so basically I want to replace " with a blank. Any help would be greatly appreciated.
Thanks
You need to escape the " sign. Like this:
nextLink1.replace("\"","");
The compiler will recognize the first two quote marks, but the third one will produce a syntax error.
Using an escape sequence will place a double quote as such:
nextLink1.replace("\"","");
You can find more escape sequences here http://docs.oracle.com/javase/tutorial/java/data/characters.html
" is Java's metacharacter used to start or end Strings literals. If you want to use it inside String literal you need to escape it first with \ like \" (which is another Java's metacharacter used for example to create new lines mark "\n").
Also blank String is not () but "". So try this way
nextLink1.replace("\"","");
BTW Strings are immutable which means this method will not affect original String, but create new one with replaced character. If you want nextLink1 to contain String with replaced characters you will need to use
nextLink1 = nextLink1.replace("\"","");

Escaping * character in java

I am trying to execute the following operation on a String.
if (combatLog.contains("//*name//*")) {
combatLog.replaceAll("//*name//*",glad.target.name);
}
The slashes are my attempt to escape the *, as it doesn't work without them. I have also tried one slash, and slashes on contains or replaceAll individually. Thanks
replaceAll() (counter-intuitively) takes a regex, not a string.
To escape a character for a regex, you need a double-backslash (doubled to escape the backslash from the string literal).
However, you don't want a regex. You should simply call replace() instead, which won't need any escaping.
You're using forward slashes. The backslash is the escape character. Furthermore, unless the string is being used for regex or something similar, you need not escape the *, or the / if thats what you're trying to escape.
If combatLog is a String, its contains method checks for a sequence of characters only. If you're looking for *name* in the string, you only need call combatLog.contains("*name*").
You are using forward slashes use the backslash: \ to escape characters
[edit]
also as slaks said you need to use replace() which accepts a string as input rather than a regex.
Don't forget about immutability of strings, and reassign the newly created string. Also, if your if block doesn't contain any more code, you don't need the if check at all.
You have 3 options:
if (combatLog.contains("*name*")) { // don't escape in contains()
combatLog = combatLog.replaceAll("\\*name\\*", replacement);// correct escape
}
// another regex based solution
if (combatLog.contains("*name*")) {
combatLog = combatLog.replaceAll("[*]name[*]", replacement);// character class
}
or without a regex
if (combatLog.contains("*name*")) {
combatLog = combatLog.replace("*name*", replacement);// literal string
}

String.replaceAll(...) of Java not working for \\ and \

I want to convert the directory path from:
C:\Users\Host\Desktop\picture.jpg
to
C:\\Users\\Host\\Desktop\\picture.jpg
I am using replaceAll() function and other replace functions but they do not work.
How can I do this?
I have printed the statement , it gives me the one which i wanted ie
C:\Users\Host\Desktop\picture.jpg
but now when i pass this variable to open the file, i get this exception why?
java.io.FileNotFoundException: C:\Users\Host\Desktop\picture.jpg
EDIT: Changed from replaceAll to replace - you don't need a regex here, so don't use one. (It was a really poor design decision on the part of the Java API team, IMO.)
My guess (as you haven't provided enough information) is that you're doing something like:
text.replace("\\", "\\\\");
Strings are immutable in Java, so you need to use the return value, e.g.
String newText = oldText.replace("\\", "\\\\");
If that doesn't answer your question, please provide more information.
(I'd also suggest that usually you shouldn't be doing this yourself anyway - if this is to include the information in something like a JSON response, I'd expect the wider library to perform escaping for you.)
Note that the doubling is required as \ is an escape character for Java string (and character) literals. Note that as replace doesn't treat the inputs as regular expression patterns, there's no need to perform further doubling, unlike replaceAll.
EDIT: You're now getting a FileNotFoundException because there isn't a filename with double backslashes in - what made you think there was? If you want it as a valid filename, why are you doubling the backslashes?
You have to use :
String t2 = t1.replaceAll("\\\\", "\\\\\\\\");
or (without pattern) :
String t2 = t1.replace("\\", "\\\\");
Each "\" has to be preceeded by an other "\". But it's also true for the preceeding "\" so you have to write four backslashes each time you want one in regex.
In strings \ is bydefault used as escape character therefore in order to select "\" in a string you have to use "\" and for "\" (i.e blackslack two times) use "\\". This will solve your problem and thos will also apply to other symbols also like "
Two explanations:
1. Replace double backslashes to one (not what you asked)
You have to escape the backslash by backslashes. Like this:
String newPath = oldPath.replaceAll("\\\\\\\\", "\\");
The first parameter needs to be escaped twice. Once for the Java Compiler and once because you use regular expressions. So you want to replace two backslashes by one. So, since we have to escape a backslash add one backslash. Now you have \\. This will be compiled to \. BUT!! you have to escape the backslash once again because the first parameter of the replaceAll method uses regular expressions. So to escape it, add a backslash, but that backslash needs to be escaped, so we get \\\\. These for backslashes represents one backslash in the regex. But you want to replace the double backslash to one. So use 8 backslashes.
The second parameter of the replaceAll method isn't using regular expressions, but it has to be escaped as well. So, you need to escape it once for the Java Compiler and once for the replace method: \\\\. This is compiled to two backslashes, which are being interpreted as 1 backslash in the replaceAll method.
2. Replace single backslash to a pair of backslashes (what you asked)
String newPath = oldPath.replaceAll("\\\\", "\\\\\\\\");
Same logic as above.
3. Use replace() instead of replaceAll().
String newPath = oldPath.replace("\\", "\\\\");
The difference is that the replace() method doesn't use regular expressions, so you don't have to escape every backslash twice for the first parameter.
Hopefully, I explained well...
-- Edit: Fixed error, as pointed out by xehpuk --

Escaping a String from getting regex parsed in Java

In Java, suppose I have a String variable S, and I want to search for it inside of another String T, like so:
if (T.matches(S)) ...
(note: the above line was T.contains() until a few posts pointed out that that method does not use regexes. My bad.)
But now suppose S may have unsavory characters in it. For instance, let S = "[hi". The left square bracket is going to cause the regex to fail. Is there a function I can call to escape S so that this doesn't happen? In this particular case, I would like it to be transformed to "\[hi".
String.contains does not use regex, so there isn't a problem in this case.
Where a regex is required, rather rejecting strings with regex special characters, use java.util.regex.Pattern.quote to escape them.
As Tom Hawtin said, you need to quote the pattern. You can do this in two ways (edit: actually three ways, as pointed out by #diastrophism):
Surround the string with "\Q" and "\E", like:
if (T.matches("\\Q" + S + "\\E"))
Use Pattern instead. The code would be something like this:
Pattern sPattern = Pattern.compile(S, Pattern.LITERAL);
if (sPattern.matcher(T).matches()) { /* do something */ }
This way, you can cache the compiled Pattern and reuse it. If you are using the same regex more than once, you almost certainly want to do it this way.
Note that if you are using regular expressions to test whether a string is inside a larger string, you should put .* at the start and end of the expression. But this will not work if you are quoting the pattern, since it will then be looking for actual dots. So, are you absolutely certain you want to be using regular expressions?
Try Pattern.quote(String). It will fix up anything that has special meaning in the string.
Any particular reason not to use String.indexOf() instead? That way it will always be interpreted as a regular string rather than a regex.
Regex uses the backslash character '\' to escape a literal. Given that java also uses the backslash character you would need to use a double bashslash like:
String S = "\\[hi"
That will become the String:
\[hi
which will be passed to the regex.
Or if you only care about a literal String and don't need a regex you could do the following:
if (T.indexOf("[hi") != -1) {
T.contains() (according to javadoc : http://java.sun.com/javase/6/docs/api/java/lang/String.html) does not use regexes. contains() delegates to indexOf() only.
So, there are NO regexes used here. Were you thinking of some other String method ?

Categories

Resources