Escaping double-slashes with regular expressions in Java - 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("\\\\", "\\");
}
The unit test is failing 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?

Use String.replace which does a literal replacement instead of String.replaceAll which uses regular expressions.
Example:
"peque\\\\u0f1o".replace("\\\\", "\\") // gives peque\u0f1o
String.replaceAll takes a regular expression thus \\\\ is interpreted as the expression \\ which in turn matches a single \. (The replacement string also has special treatment for \ so there's an error there too.)
To make String.replaceAll work as you expect here, you would need to do
"peque\\\\u0f1o".replaceAll("\\\\\\\\", "\\\\")

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

See javadoc for Matcher:
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.
Thus with replaceAll you cannot replace anything with a backslash. Thus a really crazy workaround for your case would be str.replaceAll("\\\\(\\\\)", "$1")

Related

Java String replaceAll() method using {} curly brackets

So for my app in Android Studio I want to replace the following:
String card = cards.get(count).getCard();
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("{Player1}", "Poep");
}
An example of String card can be: {Player1} switch drinks with the person next to you.
Somehow I can't use {} for the replacing. With the { it says: "Dangling metacharacter". Screenshot: https://prnt.sc/s2bbl8
Is there a solution for this?
the first Argument of replaceAll is a String that is parsed to a regalar Expression (regEx). The braces { } are special reserved meta characters to express something within the regular expression. To match them as normal characters, you need to escape them with a leading backslash \ and because the backslash is also a special character you need to escape itself with an additional backslash:
String replacedCard = card.replaceAll("\\{Player1\\}", "Poep");
Both { } are reserved regex characters. Since the replaceAll() function takes in a regex parameter, you have to explicitly state that { and } are part of your actual string. You can do this by prefixing them with the escape character: \. But because the escape character is also a reserved character, you need to escape it too.
Here's the correct way to write your code:
String card = cards.get(count).getCard();
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("\\{Player1\\}", "Poep");
}
You need to escape the initial { with \. I.e;
String card = "{Player1}";
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("\\{Player1}", "Poep");
System.out.println("replace: " + replacedCard);
}
The method String.replaceAll expects a regular expression. The other answers already give a solution for this. However, if you don't need regular expressions, then you can also use String.replace:
String replacedCard = card.replace("{Player1}", "Poep");
Since the input value of the replaceAll method expects a regex, you need to escape the curly brackets with a backslash. The curly brackets are special characters in the context of regular expressions.
In Java a backslash in a regex is accomplished by a double backslash \\ (see https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for reference).
So you would need to adjust the line like so:
String replacedCard = card.replaceAll("\\{Player1\\}", "Poep");
{} are special characters for Regular Expressions. replaceAll method takes as first parameter a Regular Expressions, so if you want also to replace the curly brackets you have to skip them with \\ , as follow:
String card = cards.get(count).getCard();
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("\\{Player1}", "Poep");
}

String index out of range with replace all

How can I replace mapDir surrounded by <> to a certain string?
String mapDir = "D:\\mapping\\specialists\\ts_gpc\\";
String test = "foo: <mapDir> -bar";
println(test.replaceAll("<mapDir>", mapDir));
The above gives me a StringIndexOutOfBoundsException.
This code below for me, but I think pure java has to work as well.
static String replaceWord(String original, String find, String replacement) {
int i = original.indexOf(find);
if (i < 0) {
return original; // return original if 'find' is not in it.
}
String partBefore = original.substring(0, i);
String partAfter = original.substring(i + find.length());
return partBefore + replacement + partAfter;
}
You dont need replaceAll method as you are not using regex. Instead you could work with replace api like below:
String mapDir = "D:\\mapping\\specialists\\ts_gpc\\";
String test = "foo: <mapDir> -bar";
System.out.println(test.replace("<mapDir>", mapDir));
replaceAll in String uses a regex, as specified in the documentation:
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; see Matcher.replaceAll. Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired.
Thus, you should escape your replacement string like this:
String mapDir = "D:\\mapping\\specialists\\ts_gpc\\";
String test = "foo: <mapDir> -bar";
System.out.println(test.replaceAll("<mapDir>", Matcher.quoteReplacement(mapDir)));
which gives the output:
foo: D:\mapping\specialists\ts_gpc\ -bar
Since replaceAll works with regex, you need to re-escape the backslashes:
String mapDir = "D:\\\\mapping\\\\specialists\\\\ts_gpc\\\\";
String test = "foo: <mapDir> -bar";
System.out.println(test.replaceAll("<mapDir>", mapDir));
Quoting this answer:
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)

Java: String split acting weird

public String getPriceString() {
String priceString = "45.0";
String[] priceStringArray = priceString.split(".");
return priceStringArray.length + "";
}
Why does this give me a 0, zero? Shouldn't this be 2?
The argument to split() is a regular expression, and dot has a special meaning in regular expressions (it matches any character).
Try priceString.split("[.]");
You need to escape . like that
String[] priceStringArray = priceString.split("\\.");
split takes regular expression as a parameter and . means any character.
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#sum
escape . with backslash like \\.. . is a regex metacharacter for anything. you will have to escape it with \\. in order to make it treat as a normal character
String priceString = "45.0";
String[] priceStringArray = priceString.split("\\.");
String.split takes a regular expression pattern. You're passing in . which means you want to split on any character.
You could use "\\." as the pattern to split on - but personally I'd use Guava instead:
private static final Splitter DOT_SPLITTER = Splitter.on('.');
...
(If you're not already using Guava, you'll find loads of goodies in there.)
You need to escape . as \\. because . has special meaning in regex.
String priceString = "45.0";
String[] priceStringArray = priceString.split("\\.");
return priceStringArray.length + "";
Use String[] priceStringArray = priceString.split("\\.");
You will have to use escape sequence.

How to split the string using '^' this special character in java?

I want to split the following string "Good^Evening" i used split option it is not split the value. please help me.
This is what I've been trying:
String Val = "Good^Evening";
String[] valArray = Val.Split("^");
I'm assuming you did something like:
String[] parts = str.split("^");
That doesn't work because the argument to split is actually a regular expression, where ^ has a special meaning. Try this instead:
String[] parts = str.split("\\^");
The \\ is really equivalent to a single \ (the first \ is required as a Java escape sequence in string literals). It is then a special character in regular expressions which means "use the next character literally, don't interpret its special meaning".
The regex you should use is "\^" which you write as "\\^" as a Java String literal; i.e.
String[] parts = "Good^Evening".split("\\^");
The regex needs a '\' escape because the caret character ('^') is a meta-character in the regex language. The 2nd '\' escape is needed because '\' is an escape in a String literal.
try this
String str = "Good^Evening";
String newStr = str.replaceAll("[^]+", "");

How to Replace dot (.) in a string in Java

I have a String called persons.name
I want to replace the DOT . with /*/ i.e my output will be persons/*/name
I tried this code:
String a="\\*\\";
str=xpath.replaceAll("\\.", a);
I am getting StringIndexOutOfBoundsException.
How do I replace the dot?
You need two backslashes before the dot, one to escape the slash so it gets through, and the other to escape the dot so it becomes literal. Forward slashes and asterisk are treated literal.
str=xpath.replaceAll("\\.", "/*/"); //replaces a literal . with /*/
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceAll(java.lang.String,%20java.lang.String)
If you want to replace a simple string and you don't need the abilities of regular expressions, you can just use replace, not replaceAll.
replace replaces each matching substring but does not interpret its argument as a regular expression.
str = xpath.replace(".", "/*/");
Use Apache Commons Lang:
String a= "\\*\\";
str = StringUtils.replace(xpath, ".", a);
or with standalone JDK:
String a = "\\*\\"; // or: String a = "/*/";
String replacement = Matcher.quoteReplacement(a);
String searchString = Pattern.quote(".");
String str = xpath.replaceAll(searchString, replacement);
return sentence.replaceAll("\s",".");

Categories