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

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

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


当前回答

我试了一下

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;
}

其他回答

我最终得到了下一个解决方案: 使用substitute()方法创建类templatessubstitute,并使用它格式化输出 然后创建一个字符串模板,并用值填充它

import java.util.*;
public class MyClass {

    public static void main(String args[]) {
    String template = "WRR = {WRR}, SRR = {SRR}\n" +
                      "char_F1 = {char_F1}, word_F1 = {word_F1}\n";
    
    Map<String, Object> values = new HashMap<>();
    values.put("WRR", 99.9);
    values.put("SRR", 99.8);
    values.put("char_F1", 80);
    values.put("word_F1", 70);
    
    String message = TemplateSubstitutor.substitute(values, template);
    
    System.out.println(message);
    }
}

class TemplateSubstitutor {
    public static String substitute(Map<String, Object> map, String input_str) {
        String output_str = input_str;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            output_str = output_str.replace("{" + key + "}", String.valueOf(value));
        }
        return output_str;
    }
    
}

截至2022年,最新的解决方案是Apache Commons Text StringSubstitutor

医生说:

// Build map
 Map<String, String> valuesMap = new HashMap<>();
 valuesMap.put("animal", "quick brown fox");
 valuesMap.put("target", "lazy dog");
 String templateString = "The ${animal} jumped over the ${target} ${undefined.number:-1234567890} times.";

 // Build StringSubstitutor
 StringSubstitutor sub = new StringSubstitutor(valuesMap);

 // Replace
 String resolvedString = sub.replace(templateString)

;

谢谢你的帮助!使用所有的线索,我写了一个例程来做我想要的——使用字典的类似python的字符串格式化。因为我是Java新手,任何提示都是感激的。

public static String dictFormat(String format, Hashtable<String, Object> values) {
    StringBuilder convFormat = new StringBuilder(format);
    Enumeration<String> keys = values.keys();
    ArrayList valueList = new ArrayList();
    int currentPos = 1;
    while (keys.hasMoreElements()) {
        String key = keys.nextElement(),
        formatKey = "%(" + key + ")",
        formatPos = "%" + Integer.toString(currentPos) + "$";
        int index = -1;
        while ((index = convFormat.indexOf(formatKey, index)) != -1) {
            convFormat.replace(index, index + formatKey.length(), formatPos);
            index += formatPos.length();
        }
        valueList.add(values.get(key));
        ++currentPos;
    }
    return String.format(convFormat.toString(), valueList.toArray());
}

另一个Apache Common StringSubstitutor的简单命名占位符的例子。

String template = "Welcome to {theWorld}. My name is {myName}.";

Map<String, String> values = new HashMap<>();
values.put("theWorld", "Stackoverflow");
values.put("myName", "Thanos");

String message = StringSubstitutor.replace(template, values, "{", "}");

System.out.println(message);

// Welcome to Stackoverflow. My name is Thanos.

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

import org.antlr.stringtemplate.*;

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