You can use the Matcher#appendReplacement , with which you can perform a replacement dynamically, based on the resulting match.
Here is an example code :
import java.util.*; import java.util.regex.*; import java.lang.*; import java.io.*; class Ideone { public static void main (String[] args) throws java.lang.Exception { String s = "Код %здесь%, кот %там%"; HashMap<String, String> h = new HashMap<String, String>(); h.put("здесь" , "на земле"); h.put("там" , "в раю"); System.out.println(convertTree(s, h)); } private static String convertTree(String s, HashMap<String, String> conv) { Pattern pattern = Pattern.compile("%(\\p{L}+)%"); // Задаем шаблон Matcher m = pattern.matcher(s); // Инициализация Matcher StringBuffer result = new StringBuffer(); // Буфер для конечного значения while (m.find()) { // Проверка на совпадение if (conv.containsKey(m.group(1))) { // Проверка на наличие ключа m.appendReplacement(result, conv.get(m.group(1))); // Подставляем значение из HashMap } else { m.appendReplacement(result, m.group(0)); // Или найденное совпадение, если ключ не найден } } m.appendTail(result); // Добавить остаток строки return result.toString(); } }