2

This function is used to replace certain substrings in a string with respective values.

// map(string_to_replace, string_to_replace_with)

String template = "ola ala kala pala sala";
StringBuilder populatedTemplate = new StringBuilder();
HashMap<String, String> map = new HashMap<>();
map.put("ola", "patola");
map.put("pala", "papala");

int i=0;
for (String word : template.split("'")) {
    populatedTemplate.append( map.getOrDefault(word, word));
    populatedTemplate.append(" ");
}

System.out.println(populatedTemplate.toString());

This above function works fine if substring to be replaced is surrounded by " "(space).

Ex- String => "Hey {how} are $=you" if substrings to be replaced is "Hey" or "you", then it works fine. The issue is when I want to replace "how" and "you".

How can I achieve this without additional complexity ?

Kedar Mhaswade
  • 4,535
  • 2
  • 25
  • 34
tarun14110
  • 940
  • 5
  • 26
  • 57
  • why not `template.replace(string_to_replace, string_to_replace_with)` as often as you need? PS: http://stackoverflow.com/questions/1324676/what-is-a-word-boundary-in-regexes might work otherwise. – zapl May 13 '16 at 19:11
  • @zapl the issue with that is the replacements are dependent. i.e let I want to replace "how" to "are", and "are" to "ok". after first iteration string would be "Hey {are} are $=you". And after 2nd iteration "Hey {ok} ok $=you". Ands that the wrong output. It should be "Hey {are} ok $=you" – tarun14110 May 13 '16 at 19:16

1 Answers1

3

I you want to replace only the words that you have in the map and keep the rest as it is, you can proceed as next:

String template = "Hey {how} are $=you";
StringBuilder populatedTemplate = new StringBuilder();
Map<String, String> map = new HashMap<>();
map.put("how", "HH");
map.put("you", "YY");
// Pattern allowing to extract only the words
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher(template);
int fromIndex = 0;
while (matcher.find(fromIndex)) {
    // The start index of the current word
    int startIdx = matcher.start();
    if (fromIndex < startIdx) {
        // Add what we have between two words
        populatedTemplate.append(template, fromIndex, startIdx);
    }
    // The current word
    String word = matcher.group();
    // Replace the word by itself or what we have in the map
    populatedTemplate.append(map.getOrDefault(word, word));
    // Start the next find from the end index of the current word
    fromIndex = matcher.end();
}
if (fromIndex < template.length()) {
    // Add the remaining sub String
    populatedTemplate.append(template, fromIndex, template.length());
}
System.out.println(populatedTemplate);

Output:

Hey {HH} are $=YY

Response Update:

Assuming that you want to be able to replace not only words but anything like ${questionNumber}, you will need to create the regular expression dynamically like this:

String template = "Hey {how} are $=you id=minScaleBox-${questionNumber}";
...
map.put("${questionNumber}", "foo");
StringBuilder regex = new StringBuilder();
boolean first = true;
for (String word : map.keySet()) {
    if (first) {
        first = false;
    } else {
        regex.append('|');
    }
    regex.append(Pattern.quote(word));
}
Pattern pattern = Pattern.compile(regex.toString());
...

Output:

Hey {HH} are $=YY id=minScaleBox-foo
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • Let String => "id=minScaleBox-${questionNumber}", and toreplaceString= "${questionNumber}". In this case it is not working. Can it be done ? – tarun14110 May 13 '16 at 21:09