在Python中,格式化字符串时,我可以按名称而不是按位置填充占位符,如下所示:

print "There's an incorrect value '%(value)s' in column # %(column)d" % \
  { 'value': x, 'column': y }

我想知道这在Java中是否可能(希望没有外部库)?


当前回答

可以使用Apache Commons StringSubstitutor。注意,StrSubstitutor已弃用。

import org.apache.commons.text.StringSubstitutor;
// ...
Map<String, String> values = new HashMap<>();
values.put("animal", "quick brown fox");
values.put("target", "lazy dog");
StringSubstitutor sub = new StringSubstitutor(values);
String result = sub.replace("The ${animal} jumped over the ${target}.");
// "The quick brown fox jumped over the lazy dog."

这个类支持为变量提供默认值。

String result = sub.replace("The number is ${undefined.property:-42}.");
// "The number is 42."

要使用递归变量替换,调用setEnableSubstitutionInVariables(true);。

Map<String, String> values = new HashMap<>();
values.put("b", "c");
values.put("ac", "Test");
StringSubstitutor sub = new StringSubstitutor(values);
sub.setEnableSubstitutionInVariables(true);
String result = sub.replace("${a${b}}");
// "Test"

其他回答

你可以使用StringTemplate库,它提供了你想要的和更多。

import org.antlr.stringtemplate.*;

final StringTemplate hello = new StringTemplate("Hello, $name$");
hello.setAttribute("name", "World");
System.out.println(hello.toString());

可以使用Apache Commons StringSubstitutor。注意,StrSubstitutor已弃用。

import org.apache.commons.text.StringSubstitutor;
// ...
Map<String, String> values = new HashMap<>();
values.put("animal", "quick brown fox");
values.put("target", "lazy dog");
StringSubstitutor sub = new StringSubstitutor(values);
String result = sub.replace("The ${animal} jumped over the ${target}.");
// "The quick brown fox jumped over the lazy dog."

这个类支持为变量提供默认值。

String result = sub.replace("The number is ${undefined.property:-42}.");
// "The number is 42."

要使用递归变量替换,调用setEnableSubstitutionInVariables(true);。

Map<String, String> values = new HashMap<>();
values.put("b", "c");
values.put("ac", "Test");
StringSubstitutor sub = new StringSubstitutor(values);
sub.setEnableSubstitutionInVariables(true);
String result = sub.replace("${a${b}}");
// "Test"

https://dzone.com/articles/java-string-format-examples字符串。format(inputString, [listOfParams])将是最简单的方法。字符串中的占位符可以按顺序定义。欲了解更多详细信息,请查看提供的链接。

这是一个旧的线程,但只是为了记录,你也可以使用Java 8风格,像这样:

public static String replaceParams(Map<String, String> hashMap, String template) {
    return hashMap.entrySet().stream().reduce(template, (s, e) -> s.replace("%(" + e.getKey() + ")", e.getValue()),
            (s, s2) -> s);
}

用法:

public static void main(String[] args) {
    final HashMap<String, String> hashMap = new HashMap<String, String>() {
        {
            put("foo", "foo1");
            put("bar", "bar1");
            put("car", "BMW");
            put("truck", "MAN");
        }
    };
    String res = replaceParams(hashMap, "This is '%(foo)' and '%(foo)', but also '%(bar)' '%(bar)' indeed.");
    System.out.println(res);
    System.out.println(replaceParams(hashMap, "This is '%(car)' and '%(foo)', but also '%(bar)' '%(bar)' indeed."));
    System.out.println(replaceParams(hashMap, "This is '%(car)' and '%(truck)', but also '%(foo)' '%(bar)' + '%(truck)' indeed."));
}

输出将是:

This is 'foo1' and 'foo1', but also 'bar1' 'bar1' indeed.
This is 'BMW' and 'foo1', but also 'bar1' 'bar1' indeed.
This is 'BMW' and 'MAN', but also 'foo1' 'bar1' + 'MAN' indeed.

我试了一下

public static void main(String[] args) 
{
    String rowString = "replace the value ${var1} with ${var2}";
    
    Map<String,String> mappedValues = new HashMap<>();
    
    mappedValues.put("var1", "Value 1");
    mappedValues.put("var2", "Value 2");
    
    System.out.println(replaceOccurence(rowString, mappedValues));
}

private static  String replaceOccurence(String baseStr ,Map<String,String> mappedValues)
{
    for(String key :mappedValues.keySet())
    {
        baseStr = baseStr.replace("${"+key+"}", mappedValues.get(key));
    }
    
    return baseStr;
}