Java string replace regex pattern with evaluated key

best wishes :

I have an input string like this

I want to go to {places} where {things} are happening.

The values for {places} and {things} are computed lazily (i.e. first i find out what all keys needs to be replaced and then compute the values for them, and then replace them in the original string).

I am able to find out all the keys and removing them using the below code.

public class Temp {
    private static final Pattern betweenCurlyBracesMatcher = Pattern.compile("\\{(.*?)\\}");

    public static void main(String args[]) {
        System.out.println(resolve2("hello {world} from {here}"));
    }

    public static String resolve2(String input) {
        Map<String, String> keyValueMap = new HashMap<>();
        Matcher matcher = betweenCurlyBracesMatcher.matcher(input);
        while (matcher.find()) {
            String key = matcher.group(1);
            if (!keyValueMap.containsKey(key)) {
                keyValueMap.put(key, computeValueForKey(key));
            }
        }
        for (Map.Entry<String, String> entry : keyValueMap.entrySet()) {
            input = input.replace("{" + entry.getKey() + "}", entry.getValue());  // << ugly code here
        }
        return input;
    }

    private static String computeValueForKey(String key) {
        return "new" + key;
    }
}

but I am not happy with

input = input.replace("{" + entry.getKey() + "}", entry.getValue());

because it means whenever i change my regex i will have to update this logic. Is there a more elegant solution to this problem.


input hello {world} from {here}

output hello newworld from newhere


input I want to go to {places} where {things} are happening.

output I want to go to newplaces where newthings are happening.

Tim Biegeleisen :

You should make use of the Matcher#appendReplacement and Matcher#appendTail APIs here:

Map<String, String> keyValueMap = new HashMap<>();
keyValueMap.put("places", "to America");
keyValueMap.put("things", "events");
String input = "I want to go to {places} where {things} are happening.";
Pattern pattern = Pattern.compile("\\{(.*?)\\}");
Matcher matcher = pattern.matcher(input);
StringBuffer buffer = new StringBuffer();

while(matcher.find()) {
    matcher.appendReplacement(buffer, keyValueMap.get(matcher.group(1)));
}
matcher.appendTail(buffer);
System.out.println(buffer.toString());

This prints:

I want to go to to America where events are happening.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=358765&siteId=1