[Java]_ [primary]_ [replace multiple placeholders for strings with multiple values using regular efficient]

Posted by Vbabiy on Thu, 21 Oct 2021 07:53:10 +0200

scene

  1. When developing Java programs based on template content, such as an email content template, place placeholders $email,$name, etc. in the content as symbols to replace the actual content. So what can we do at this time to reduce the generation of unnecessary String strings, so as to reduce the memory consumption and achieve the purpose of one-time replacement?

explain

  1. As an immutable String, using its replace method to replace it will generate a new String. This String is obviously inappropriate, so you have to use a variable String.

  2. Variable strings can use either StringBuilder or StringBuffer, and they all have a replace(start, end, str) and indexOf(str, fromIndex) method. In this case, the most basic way is to search each placeholder by indexOf, and then replace the placeholder by the replace method.

  3. The specific method is to use a new StringBuffer(StringBuilder) as temporary storage, add the searched placeholders to the new StringBuffer, and other non placeholders are also added to the StringBuffer in order. Finally, this StringBuffer can be used as a new replaced string.

  4. In the Java standard library, the above scheme can be easily implemented using Regex regularization. You can add mismatched strings and substitution strings through the appendReplacement[1] method of Matcher, and then add the remaining mismatched strings with appendTail. See the example for details

  5. Problem to be solved: Java regularization does not find a way to set multiple values

example

  1. Method uses a Map to match the matching string, and then replaces it with the associated value.
package com.example.string;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.jupiter.api.Test;

public class StringReplaceTest {

/**
     *
     * StringBuffer sb = new StringBuffer();
     * HashMap<String, String> oldToNew = new HashMap<>();
     * oldToNew.put("$sn",sn);
     * oldToNew.put("$email",mail);
     * StringUtils.replaceOneMore(sb,registertemplate,"[$]sn|[$]email",oldToNew);
     *
     * @param output
     * @param input
     * @param oldRegex
     * @param oldToNew
     */
    public static void replaceOneMore(StringBuffer output, String input,
                                      String oldRegex, Map<String,String> oldToNew){
        Pattern p = Pattern.compile(oldRegex);
        Matcher m = p.matcher(input);
                                            
        while (m.find()) {
            String one = m.group();
            if(oldToNew.containsKey(one))
                m.appendReplacement(output, oldToNew.get(one));
        }
        m.appendTail(output);
    }

    public static<T> void print(String key,T t){
        System.out.println(key +" : "+t);
    }

    @Test
    public void testReplaceStringByRegexOrPredicate(){
        StringBuffer sb = new StringBuffer();
        HashMap<String, String> oldToNew = new HashMap<>();
        oldToNew.put("$name","Tobey");
        oldToNew.put("$email","test@gmail.com");
        String registertemplate = "my name is $name, my email is $email, you can send to email to $email.";
        replaceOneMore(sb,registertemplate,"[$]name|[$]email",oldToNew);
        print("New String is: ",sb.toString());
    }



}

output

New String is:  : my name is Tobey, my email is test@gmail.com, you can send to email to test@gmail.com.

reference resources

  1. Matcher Java Platform SE 8

  2. can-i-replace-groups-in-java-regex

  3. Regular expression question mark colon?: Use_ hxkjnet360 column

  4. Usage of question mark (?) in regular expression_ Xiaomin's column

Topics: Java