在Python中,格式化字符串时,我可以按名称而不是按位置填充占位符,如下所示:
print "There's an incorrect value '%(value)s' in column # %(column)d" % \
{ 'value': x, 'column': y }
我想知道这在Java中是否可能(希望没有外部库)?
在Python中,格式化字符串时,我可以按名称而不是按位置填充占位符,如下所示:
print "There's an incorrect value '%(value)s' in column # %(column)d" % \
{ 'value': x, 'column': y }
我想知道这在Java中是否可能(希望没有外部库)?
当前回答
您应该看看官方的ICU4J库。它提供了一个类似于JDK的MessageFormat类,但前者支持命名占位符。
与本页提供的其他解决方案不同。ICU4j是ICU项目的一部分,由IBM维护并定期更新。此外,它还支持高级用例,如多元化等。
下面是一个代码示例:
MessageFormat messageFormat =
new MessageFormat("Publication written by {author}.");
Map<String, String> args = Map.of("author", "John Doe");
System.out.println(messageFormat.format(args));
其他回答
基于这个答案,我创建了MapBuilder类:
public class MapBuilder {
public static Map<String, Object> build(Object... data) {
Map<String, Object> result = new LinkedHashMap<>();
if (data.length % 2 != 0) {
throw new IllegalArgumentException("Odd number of arguments");
}
String key = null;
Integer step = -1;
for (Object value : data) {
step++;
switch (step % 2) {
case 0:
if (value == null) {
throw new IllegalArgumentException("Null key value");
}
key = (String) value;
continue;
case 1:
result.put(key, value);
break;
}
}
return result;
}
}
然后我创建类StringFormat用于字符串格式化:
public final class StringFormat {
public static String format(String format, Object... args) {
Map<String, Object> values = MapBuilder.build(args);
for (Map.Entry<String, Object> entry : values.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
format = format.replace("$" + key, value.toString());
}
return format;
}
}
你可以这样用:
String bookingDate = StringFormat.format("From $startDate to $endDate"),
"$startDate", formattedStartDate,
"$endDate", formattedEndDate
);
不幸的是,答案是否定的。然而,你可以非常接近一个合理的语法:
"""
You are $compliment!
"""
.replace('$compliment', 'awesome');
它比String更具可读性和可预测性。至少是格式!
我最终得到了下一个解决方案: 使用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)
;
jakarta commons lang的StrSubstitutor是一种轻量级的实现方法,前提是您的值已经被正确格式化。
http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/text/StrSubstitutor.html
Map<String, String> values = new HashMap<String, String>();
values.put("value", x);
values.put("column", y);
StrSubstitutor sub = new StrSubstitutor(values, "%(", ")");
String result = sub.replace("There's an incorrect value '%(value)' in column # %(column)");
上述结果为:
“第2列中的“1”值不正确”
当使用Maven时,您可以将此依赖项添加到pom.xml:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>