Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java String replaceAll Recursive behavior

Yesterday I was working on customized letters and memos. And I have made mapping keywords, like: [Dateofbirth], [Email], [Employee], [Salary] etc, which will be replace at the time of generation.

Example: dear [Employee], your Current Salary is [Salary].

expected output:

Output: dear John, your Current Salary is 12000.

I am using replaceAll() method here is a code.

   String str = "dear [Employee], your Current Salary is [Salary].";
        Map<String,String> vals = new HashMap<String,String>();
        vals.put("[Employee]","John");
        vals.put("[Salary]","12000");
        for(String key:vals.keySet()){
            str=str.replaceAll(key,vals.get(key));
        }
        System.out.println(str);

but the out is:

dJohn1200012000 [JohnJohnJohnJohnJohnJohnJohnJohn], JohnJohnu12000 Cu1200012000Johnnt 1200012000John1200012000John is [1200012000John1200012000John].

I was confused and Googled it and tried to make it correct, after that I changed replaceAll() with replace()

EX: str=str.replace(key,vals.get(key));

Now it is working fine. The question is Why replace all is doing such kind of behavior what is the core concept of replaceAll() and When to use replace() when to use replaceAll(). Thanks

like image 983
Saqib Ahmed Avatar asked Mar 07 '23 00:03

Saqib Ahmed


1 Answers

Before going to your problem, I hope you know about String#format that Java API have. With that you could simply write

String formattedString = String.format("dear %s, your Current Salary is %.2f", "John", 12000.45);
System.out.println(formattedString);

If you are doing that yourself for unavoidable situations, replaceAll treats the first parameter as a regex and not normal string to replace.

From docs of replaceAll.

Replaces each substring of this string that matches the given regular expression with the given replacement.

Since your parameter consists of [and] and they are matching with each character inside them.

It will work if you get rid of that [] and use any other special characters that are not meta characters for ex #.

    String str = "dear #Employee#, your Current Salary is #Salary#.";
    Map<String, String> vals = new HashMap<String, String>();
    vals.put("#Employee#", "John");
    vals.put("#Salary#", "12000");
    for (String key : vals.keySet()) {
        str = str.replaceAll(key, vals.get(key));
    }
    System.out.println(str);

gives you

dear John, your Current Salary is 12000.

Or simply use replace() as you said in the end.

like image 194
Suresh Atta Avatar answered Mar 09 '23 19:03

Suresh Atta