ReplaceAll and " doesn't replace - java

Can anyone point me out how the first if works and the second doesn't? I'm puzzled why the second if-clause isn't working. I'd like to get a hint, thanks.
String msg = o.getTweet();
if (msg.indexOf("&") > 0) {
msg = msg.replaceAll("&", "&");// vervangt & door &
}
if (msg.indexOf(""") > 0) {
msg = msg.replaceAll(""", "aa"); //vervangt " door "
}

Because ZERO is a very valid index. Try this out,
String msg = o.getTweet();
if (msg.indexOf("&") != -1) {
msg = msg.replaceAll("&", "&");// vervangt & door &
}
if (msg.indexOf(""") != -1) {
msg = msg.replaceAll(""", "aa"); //vervangt " door "
}
Explanation:
The documentation of String.indexOf(String str) explains that, "if the string argument occurs as a substring within this object, then the index of the first character of the first such substring is returned; if it does not occur as a substring, -1 is returned." - [link to docs]
This can be done as simple as below, as OpenSauce pointed out here.
msg = msg.replace("&", "&").replace(""", "\"");
Useful links:
String indexOf() docs
String replace() docs
String replaceAll() docs

You don't need to check the substring exists, the replace and replaceAll methods are no-ops if the substring is not found. Since you're not looking for regexes, you can also use replace instead of replaceAll - it will be somewhat more efficient, and won't surprise you if you also want to check for other strings which happen to contain regex special chars.
msg = msg.replace("&", "&").replace(""", "\"");
note that replace does indeed replace all matches, like you want. The difference between replace and replaceAll is whether the arg is interpreted as a regex or not.

Related

Replace characters and keep only one of these characters

Can someone help me here? I dont understand where's the problem...
I need check if a String have more than 1 char like 'a', if so i need replace all 'a' for a empty space, but i still want only one 'a'.
String text = "aaaasomethingsomethingaaaa";
for (char c: text.toCharArray()) {
if (c == 'a') {
count_A++;//8
if (count_A > 1) {//yes
//app crash at this point
do {
text.replace("a", "");
} while (count_A != 1);
}
}
}
the application stops working when it enters the while loop. Any suggestion? Thank you very much!
If you want to replace every a in the string except for the last one then you may try the following regex option:
String text = "aaaasomethingsomethingaaaa";
text = text.replaceAll("a(?=.*a)", " ");
somethingsomething a
Demo
Edit:
If you really want to remove every a except for the last one, then use this:
String text = "aaaasomethingsomethingaaaa";
text = text.replaceAll("a(?=.*a)", "");
You can also do it like
String str = new String ("asomethingsomethingaaaa");
int firstIndex = str.indexOf("a");
firstIndex++;
String firstPart = str.substring(0, firstIndex);
String secondPart = str.substring(firstIndex);
System.out.println(firstPart + secondPart.replace("a", ""));
Maybe I'm wrong here but I have a feeling your talking about runs of any single character within a string. If this is the case then you can just use a little method like this:
public String removeCharacterRuns(String inputString) {
return inputString.replaceAll("([a-zA-Z])\\1{2,}", "$1");
}
To use this method:
String text = "aaaasomethingsomethingaaaa";
System.out.println(removeCharacterRuns(text));
The console output is:
asomethingsomethinga
Or perhaps even:
String text = "FFFFFFFourrrrrrrrrrrty TTTTTwwwwwwooo --> is the answer to: "
+ "The Meeeeeaniiiing of liiiiife, The UUUniveeeerse and "
+ "Evvvvverything.";
System.out.println(removeCharacterRuns(text));
The console output is........
Fourty Two --> is the answer to: The Meaning of life, The Universe and Everything.
The Regular Expression used within the provided removeCharacterRuns() method was actually borrowed from the answers provided within this SO Post.
Regular Expression Explanation:

indexOf() vs regex for identifying special characters like $ and {

I would like to check if a special character like { or $is present in a string or not. I used regexp but during code review I was asked to use indexOf() instead regex( as its costlier). I would like to understand how indexOf() is used to identify special characters. (I familiar that this can be done to index substring)
String photoRoot = "http://someurl/${TOKEN1}/${TOKEN2}";
Pattern p = Pattern.compile("\\$\\{(.*?)\\}");
Matcher m = p.matcher(photoRoot);
if (m.find()) {
// logic to be performed
}
There are more then one indexOf(...) methods but all of them treat all characters the same, there is no need to escape any characters while using these methods.
Here is how you can get the two tokens by using some of the indexOf(...) methods:
String photoRoot = "http://someurl/${TOKEN1}/${TOKEN2}";
String startDelimiter = "${";
char endDelimiter = '}';
int start = -1, end = -1;
while (true) {
start = photoRoot.indexOf(startDelimiter, end);
end = photoRoot.indexOf(endDelimiter, start + startDelimiter.length());
if (start != -1 && end != -1) {
System.out.println(photoRoot.substring(start + startDelimiter.length(), end));
} else {
break;
}
}
If you're only looking to find a couple of different special characters you'd just use indexOf("$") or indexOf("}"). You will need to specify each special character you want to find separately.
There is no way though to have it find the index of every special character in one statement: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int)
If you just need to check for 2 characters as in your question, the answer will be
var found = photoRoot.indexOf("$") >=0 ||| photoRoot.indexOf("?") >=0;
It's always difficult to guess while there is contradicting information. The code does not look for special characters, it searches for a pattern - and indexOf will not help you there.
Titus' answer is good for avoiding pattern matching if you need to find the pattern ${...} (as opposed to "identifying special characters")
If (as the reviewer appears to think) you just need to look for any of a set of special characters you can apply indexOf( on_special_char ) repeatedly, but you can also do
for( int i = 0; i < photoRoot.length(); ++i ){
if( "${}".indexOf( photoRoot.charAt(i) ) >= 0 ){
// one of the special characters is at pos i
}
}
Not sure where the performance "break even" between multiple indexOf calls on the target string and the (above) iteration on the target with indexOf on the (short) string containing the specials is. But it may be easier to maintain and permits dynamic adaption to the set of specials.
Of course, the simple
photoRoot.matches( ".*" + Pattern.quote( specials ) + ".*" );
is also dynamically adaptable.

Regular expressions: ignore what is quoted in a string

If I have the string "This is > than" something 1=3 and "else = true" (dont try to understand what it means, its just an example:P ) how can i replace a custom pattern that is not contained by quotes? For example replace the '='(equals) operator, the first one, with lets say '<' resulting in the string "This is > than" something 1<3 and "else = true". Thank you in advance.
You could try the below regex to replace all the = which was present outside the " with < symbol.
=(?=(?:[^"]*"[^"]*")*[^"]*$)
Replacement string:
<
DEMO
System.out.println("\"This is > than\" something 1=3 and \"else = true\"".replaceAll("=(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", "<"));
Output:
"This is > than" something 1<3 and "else = true"
You can use this search pattern:
=(?=(?:(?:[^"]*"){2})*[^"]*$)
And replace it by:
<
RegEx Demo
In Javacode:
String repl = str.replaceAll("=(?=(?:(?:[^"]*"){2})*[^"]*$)", "<");
//=> "This is > than" something 1<3 and "else = true"
While other answers seems simple they are based on idea of testing if founded = is outside quotation by making sure that each " after it has its closing ", which means that this regex need to iterate over rest of the string from = you are testing. This can be very ineffective if your string is long and you have many = in it to test.
Alternative way to solve this problem could be finding either quoted areas or searched substrings. Then if we wind quoted area we don't change it, but when we find = we can apply different logic (we can change it to something else like in your case <). This solution has this advantage that while finding for quoted area we can consume all non-quote characters, so we will also consume = which we don't want to change, which means that if we will match = we are sure that it wasn't inside "..." so we can avoid time consuming test from other answers.
Possible code for such solution can look like
String text = "\"This is > than\" something 1=3 and \"else = true\"";
// This regex will search for areas which starts with ", ends with " and have zero
// or more non quotation marks between them. If such area will be found it will be
// placed in group named "quotation". Searching for such group have higher priority so
// I put this variant before `=` variant (or other variants)
Pattern p = Pattern.compile("(?<quotation>\"[^\"]*\")|>=|=|<|>");
Matcher m = p.matcher(text);
StringBuffer sb = new StringBuffer();
while (m.find()) {
if (m.group("quotation") != null) {
m.appendReplacement(sb, m.group("quotation"));
} else {
m.appendReplacement(sb, "<");
}
}
m.appendTail(sb);
String result = sb.toString();
System.out.println(result);
Output: "This is > than" something 1<3 and "else = true"

replace ". " with "\n\n" within a string in Android

I try to replace ". " with "\n\n" within a string but it doesnt work, I use the following code:
text=text.replace(". ","\n\n");
The result is every word without the last letter of the word in a each line. I read something like the point means any character in this case, but how can I actually refer to the point?
Input Example: "Hello world"
Example of the output:
Hell
world
Thank you
There is something fishy here; either text is not a String, or you don't use .replace() but something else (.replaceAll()?), or Android's .replace() is buggy.
And I frankly doubt that Android devs would have had such an overlook.
The Javadoc for String#replace() says:
Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence. [emphasis mine]
Unlike its sibling methods (.replaceFirst() and .replaceAll()) which do use regexes, .replace() doesn't (and the fact that internally it does use Pattern, at least in Oracle's JDK [*], is not the problem).
Therefore, if you actually use .replace() and gain the result you say, this is a bug in Android. If this is the case, try an alternative, like so (UNTESTED):
public static String realStringReplace(final String victim, final String target,
final String replacement)
{
final int skip = target.length();
final StringBuilder sb = new StringBuilder(victim.length());
String tmp = victim;
int index;
while (!tmp.isEmpty()) {
index = tmp.indexOf(target);
if (index == -1)
break;
sb.append(tmp.subString(0, index)).append(replacement);
tmp = tmp.subString(index + skip);
}
return sb.append(tmp).toString();
}
the point means any character if you use
text=text.replaceAll(". ", "\n\n");
perhaps you have posted the wrong code, in this case try this one:
text=text.replaceAll("\\. ", "\n\n");
the strange thing is that this line is equivalent to the line that you have posted..

How to remove the degrees celsius symbol from a string (java)

I've been trying to remove the degree Celsius symbol from the following string for a few hours now. I've looked at prior posts and I see that /u2103 is the unicode representation for it. Despite trying to remove that string, I've still had no luck. Here's what I have now:
String temp = "Technology=Li-poly;Temperature=23.0 <degree symbol>C;Voltage=3835";
StringBuilder filtered = new StringBuilder(temp.length());
for (int i = 0; i < temp.length(); i++) {
char test = temp.charAt(i);
if (test >= 0x20 && test <= 0x7e) {
filtered.append(test);
}
}
temp = filtered.toString();
temp.replaceAll(" ", "%20");
The resulting string looks like this:
Technology=Li-poly;Temperature=23.0 C;
I've also tried
temp.replaceAll("\\u2103", "");
temp.replaceChar((char)0x2103, ' ');
But none of this works.
My current problem is that the function to filter the string leaves a blank space but the call to replaceAll(" ", "%20") doesn't seem to recognize that particular space. ReplaceAll will replace other spaces with %20.
This is one problem:
temp.replaceAll(" ", "%20");
You're calling replaceAll but never using the result. Strings are immutable - any method which looks like it's changing the content is actually returning the different string as a result. You want:
temp = temp.replaceAll(" ", "%20");
Having said that, it's not clear why you're trying to replace the space at all, nor what's wrong with your resulting string.
You've got the same problem with your other temp.replaceAll and temp.replaceChar calls.
Your attempt to replace the character directly would also fail as you're escaping the backslash - you really want:
temp = temp.replace("\u2103", "");
Note the use of replace instead of replaceAll - the latter uses regular expressions, which there's no need to use at all here.
Perhaps you could leverage the Character.isWhiteSpace() function.

Categories

Resources