I have this String:
String line = "Hello John; , my name is also John.";
and this String:
String word = "John";
char c = "-";
and want this output:
"Hello -John-; , my name is also -John-."
Here's what i've managed to do so far:
public String changeString(String line, String word, char c){
String result = null;
if(line.toLowerCase().contains(word.toLowerCase())){
result = line.replaceAll(word, c + word + c);
}
return result;
}
However, with this function i get this output:
String result = "Hello -John;- , my name is also -John.-";
How can I solve this ?
UPDATE:
if i have an array instead of only one word, how can i make this work ?
import java.util.*;
import java.lang.*;
import java.io.*;
class Text
{
public static void main(String[] args) throws Exception {
String line = "Hello John; , my name: is also John.";
String[] words = {"John","name"};
char c = '-';
changeString(line, words, c);
}
public static void changeString(String line, String[] words, char c) {
String result = null;
for(int i = 0; i < words.length; i++){
if (line.toLowerCase().contains(words[i].toLowerCase())) {
result = line.replaceAll(words[i], c + words[i] + c);
}
else
result = line;
}
System.out.println(result);
}
}
Because the output is not the desired:
"Hello John; , my -name-: is also John."
Instead of :
result = line.replaceAll(word, c + word + c);
Use:
result = line.replace(word, c + word + c);
Note aside:
You might be using john. instead of john and replaceAll api uses regex as argument. Also character is defined with single quotes rather than double quotes like char c = '-';
contains
and replaceAll
is case-sensitive. Just because you will find your token with contains
on lower-case version of string, doesn't mean that replaceAll
will be able to find it too.
For instance for string like "Hello wordl"
and token "hello"
line.toLowerCase().contains(words[i].toLowerCase())
will return true
, but
line.replaceAll(words[i], c + words[i] + c);
will not work because words[i]
will be hello
but line
will contain Hello
.
Actually this condition gives you nothing
if (line.toLowerCase().contains(words[i].toLowerCase()))
It iterates over string to find your word, but replace
or replaceAll
still have to iterate over entire string on their own to find matching parts which needs to be replaced.
If you want to make sure that you will be able to find tokens regardless of case sensitivity make regex argument case-insensitive. You can do it by adding (?i)
flag to it. But if you will want to use regex also make sure that you will escape all its metacharacters like .
+
*
?
. To do it you can simply use Pattern.quote(regex)
.
So your code can look like
line.replaceAll("(?i)"+Pattern.quote(words[i]),c + words[i] + c);
If you want to match only entire words you will need to also surround your regex with word-boundary \\b
.
line.replaceAll("(?i)\\b"+Pattern.quote(words[i])+"\\b", c + words[i] + c);
Second problem in your code is that in
result = line.replaceAll(words[i], c + words[i] + c);`
you are overriding current value of result
with new result of replacing value in line
. But you forgot that line
doesn't change . It means that if you replace John
and store it in result
you will still have original John
in line
. This means that next when you will try to replace name
line.replaceAll(name, ...)
will return you John (without replacement).
To correct this problem you can simply store result of replacement in line
itself like
line = line.replaceAll(words[i], c + words[i] + c);
instead of some result
.
So your final code can look like this
public static void changeString(String line, String[] words, char c) {
for (int i = 0; i < words.length; i++) {
line = line.replaceAll(words[i], c + words[i] + c);
}
System.out.println(line);
}
But there is one other problem you may wan to solve, what if you would like to replace X
with Y
and Y
with X
? I mean something like AB X DE Y FG
into AB Y DE X FG
.
If you use your approach in first iteration you will get rid of all X
elements and replace them with Y
, which will give you
AB X DE Y FG
AB Y DE Y FG
but in second approach you will replace all Y
with X
AB Y DE Y FG
AB X DE X FG
which will finally give you AB X DE X FG
instead of AB Y DE X FG
.
To solve this kind of problems you should consider finding all your element in one loop, in which you will iterate over all characters and check if they match any of searched elements . You can solve this kind of problem for instance by using approach one of my previous answers: Replace While Pattern is Found
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.