简体   繁体   中英

Replacing strings with strings in Java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM