Java Recursive String replaceAll

Yesterday I worked on personalized letters and notes. And I made cartographic keywords, such as: [Date of birth], [Email], [Employee], [Salary], etc., which will be replaced during the generation.

Example: dear [Employee], your current salary is [Salary].

expected output:

Conclusion: dear John, your current salary is 12,000.

I am using replaceAll() method, here is the 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 output:

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

I was confused and looked for it and tried to make it correct, after which I changed replaceAll() to replace()

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

Now it works fine. The question is why replacing everyone does this, which is the basic concept of replaceAll() and when to use replace() , when to use replaceAll() . Thanks

+5
source share
7 answers

Before moving on to your problem, I hope you know about String # format , which has a Java API. With this you could just write

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

If you do this yourself for unavoidable situations, replaceAll treats the first parameter as a regular expression, not a normal replacement string.

From docs replaceAll.

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

Since your parameter consists of [ and ] , and they correspond to each character inside them.

It will work if you get rid of this [] and use any other special characters that are not metacharacters 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 just use replace() as you said at the end.

+3
source

Let's look at the javadocs of the replace and replaceAll methods. Go to javadocs

Instead

 public String replace(CharSequence target, CharSequence replacement) 

Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence. the replacement starts from the beginning of the line to the end, for example, replacing "aa" with "b" in the string "aaa" will result in "ba" rather than "ab".

Thus, in simple words, he replaces all target words with replacement words.

replaceAll

 public String replaceAll(String regex, String replacement) 

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

To understand this behavior, it is important to understand how a regular expression works. Regex is a world in its own, however we can discuss this regex here.

Square brackets group a character set together. When you call any character in this set, a match is obtained.

For example: [abc] will match all parameters a, b and c. Since replaceAll uses regex to match, it would replace all a, b, and c with the replacement string.

+2
source

replaceAll() matches the regex .
replace() matches plain text.

The [Employee] regular expression is a character class that matches any single character that is either E , m , p , l , o , y or E

+1
source

replaceAll treats the first parameter as a regular expression. Therefore, you need to avoid certain regular expression characters, which in your case [and]. They mean a character set, so replaceAll matches each character in that set and replaces the value you specified. Try to get the desired result instead -

 vals.put("\\[Employee\\]","John"); vals.put("\\[Salary\\]","12000"); 

Here we avoid the special character [and], so it no longer treats it as a set.

Work program - https://www.ideone.com/2hCbIM

+1
source

ReplaceAll compiles the regular expression and applies to the string. In this case, since your key has a "[", it will match any of the characters present inside. Therefore, for each case, it is replaced by the value

0
source

replaceAll () expects a regular expression , but replace () expects an exact string (char sequence). A regular expression requires its special characters to be escaped. Therefore, when you just want to replace the string, use the replace () method, and when you want to match the regular expression and need to be replaced, use replaceAll ().

0
source

This link may be useful for you to understand. In principle, there is only a difference: replaceAll replaces all lines that match regex provided as an argument, and replace() is replaced based on chars .

0
source

Source: https://habr.com/ru/post/1275065/


All Articles