Java 正则表达式:将所有 ${placeholders} 替换为地图值

Java Regex: Replace all ${placeholders} with map values

我正在尝试用占位符查找映射中的值替换所有出现的 ${placeholders} -> 值

下面的代码还不够完整。

Expected :[foobar, foobar, foobar, afoobbarc]
Actual   :[foobar, foobar, ${key1}bar, a${key1}bbarc]

谁能想到更好的正则表达式?

private static final Pattern replaceRegex = Pattern.compile(".*(\$\{?([^}]+)}).*");
public static String resolvePlaceholder(Map<String, String> map, String s){
  String returnValue = s;
  for (Matcher m = replaceRegex.matcher(s); m.find(); ) {
    if (map.containsKey(m.group(2))) {
      returnValue = returnValue.replace(m.group(1), map.get(m.group(2)));
    }
  }
  return returnValue;
}

@Test
public void test() {
  // Given a map of a million entries
  Map<String, String> veryBigMap = new HashMap<>();
  veryBigMap.put("key1", "foo");
  veryBigMap.put("key2", "bar");
  // And test cases
  Stream<String> testCases = Stream.of("${key1}bar", "foo${key2}", "${key1}${key2}", "a${key1}b${key2}c");

  // When resolving placeholders
  List<String> actual = testCases
      .map(t -> resolvePlaceholder(veryBigMap, t))
      .collect(Collectors.toList());

  // Then placeholders get replaced
  assertEquals(
      Arrays.asList("foobar", "foobar", "foobar", "afoobbarc"),
      actual);
}

非常感谢

菲尔

以下版本使用 StringBuffer 迭代构建输出字符串,应该可以工作:

private static final Pattern replaceRegex = Pattern.compile("\$\{(.*?)\}");

public static String resolvePlaceholder(Map<String, String> map, String s) {
    StringBuffer sb = new StringBuffer();
    Matcher m = replaceRegex.matcher(s);

    while (m.find()) {
        m.appendReplacement(sb, map.get(m.group(1)));
    }

    m.appendTail(sb);

    return sb.toString();
}