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
word? (I suspect it's"John.".)replaceAll()unless you want to do a regex replacement. Usereplace()instead.