Java:替换多个字符串占位符的最快方法

7

在Java中,最快的替换多个占位符的方法是什么?

例如:我有一个包含多个占位符的字符串,每个占位符都有一个字符串占位符名称。

String testString = "Hello {USERNAME}! Welcome to the {WEBSITE_NAME}!";

同时还有一个地图,其中包含了哪个占位符将被放置到哪个值的地图。

Map<String, String> replacementStrings = Map.of(
                "USERNAME", "My name",
                "WEBSITE_NAME", "My website name"
        );

在Java中,使用Map替换所有占位符的最快方法是什么?是否可以一次性更新所有占位符?

(请注意,我无法更改占位符格式为{1},{2}等)


问题看起来相似。不同之处在于我想知道是否可以一次性完成(而不是将String替换多次,与我的Map keyset一样)。我可能可以通过类似的代码(for循环和逻辑)实现这个目标,但我希望找到Java中已经有的能够完成此操作的方法。 - Tamanna_24
如果有一个漂亮的一行代码,那么它将是该问题的有效答案,因此我怀疑是否存在这样的代码。可能会有一些库可以做到这一点,但最终仍然需要循环遍历映射/字符串。 - Ivar
我明白了 :( 既然如此,我会关闭这个问题。 - Tamanna_24
将文本进行分词并通过从左到右迭代标记来替换。建议使用“replace”或“replaceAll”的答案都需要完整的一遍扫描,这可能会降低性能。当您的映射包含1000个或更多条目时,这将成为一个因素。 - Zabuzard
@Zabuza 这正是我的担忧!对于我的情况,每个键只会出现一次,所以我不需要完整的遍历。 - Tamanna_24
2个回答

14
你可以尝试使用StrSubstitutor(Apache Commons)链接
String testString = "Hello {USERNAME}! Welcome to the {WEBSITE_NAME}!";
Map<String, String> replacementStrings = Map.of(
                "USERNAME", "My name",
                "WEBSITE_NAME", "My website name"
        );
StrSubstitutor sub = new StrSubstitutor(replacementStrings , "{", "}");
String result = sub.replace(testString );

2
工作得非常好。谢谢!也许可以编辑为“StringSubstitutor”,因为“StrSubstitutor”已经过时了? :) - Tamanna_24

0
您可以使用以下方法来实现:
public static String replacePlaceholderInString(String text, Map<String, String> map){
    Pattern contextPattern = Pattern.compile("\\{[\\w\\.]+\\}");
    Matcher m = contextPattern .matcher(text);
    while(m.find()){
        String currentGroup = m.group();
        String currentPattern = currentGroup.replaceAll("^\\{", "").replaceAll("\\}$", "").trim();
        String mapValue = map.get(currentPattern);
        if (mapValue != null){
            text = text.replace(currentGroup, mapValue);
        }
    }
    return text;
}

内部的 replaceAll 应该改为 currentGroup.substring(1, currentGroup.length() - 1) - Roland Illig
如果替换映射包含将a映射到{a} {a} {a}的条目,会怎样? - Roland Illig
将大括号替换为空字符串或使用子字符串操作是相同的。从性能角度考虑,我认为子字符串操作会更好。我们应该使用子字符串操作。谢谢。 - user9065831
如果map中包含a到{a} {a} {a},那么该方法每次只替换键而不替换map中的值,否则将会创建一个无限循环。 - user9065831

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接