简单的问题,但是我如何格式化字符串
“{2}的{1}步”
用Java代替变量?用c#很简单。
简单的问题,但是我如何格式化字符串
“{2}的{1}步”
用Java代替变量?用c#很简单。
当前回答
这个解决方案对我很有效。我需要动态地为REST客户端创建url,所以我创建了这个方法,所以你只需要像这样传递restURL
/customer/{0}/user/{1}/order
并添加尽可能多的参数:
public String createURL (String restURL, Object ... params) {
return new MessageFormat(restURL).format(params);
}
你只需要像这样调用这个方法:
createURL("/customer/{0}/user/{1}/order", 123, 321);
输出
“用户/客户/ 123 / / 321 /秩序”
其他回答
这个解决方案对我很有效。我需要动态地为REST客户端创建url,所以我创建了这个方法,所以你只需要像这样传递restURL
/customer/{0}/user/{1}/order
并添加尽可能多的参数:
public String createURL (String restURL, Object ... params) {
return new MessageFormat(restURL).format(params);
}
你只需要像这样调用这个方法:
createURL("/customer/{0}/user/{1}/order", 123, 321);
输出
“用户/客户/ 123 / / 321 /秩序”
看一下String.format。但是请注意,它的格式说明符类似于C的printf系列函数——例如:
String.format("Hello %s, %d", "world", 42);
会返回"Hello world, 42"在学习格式说明符时,您可能会发现这很有帮助。Andy Thomas-Cramer好心地在下面的评论中留下了这个链接,它似乎指向了官方规范。最常用的是:
%s -插入一个字符串 %d -插入有符号整数(十进制) 插入一个实数,标准表示法
这与c#完全不同,c#使用带有可选格式说明符的位置引用。这意味着你不能做这样的事情:
String.format("The {0} is repeated again: {0}", "word");
…而不需要重复传递给printf/format的参数。(请看下面The Scrum Meister的评论)
如果您只想直接打印结果,您可以找到System.out.printf (PrintStream.printf)。
Apache Commons StringSubstitutor提供了一种简单易读的方法来使用命名变量格式化字符串。
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"
如果您选择不使用String。格式,另一个选项是+二进制运算符
String str = "Step " + a + " of " + b;
这相当于
new StringBuilder("Step ").append(String.valueOf(1)))。append(String.valueOf(2));
你用哪一种都是你的选择。StringBuilder更快,但速度差异很小。我更喜欢使用+操作符(它执行StringBuilder.append(String.valueOf(X))),并且发现它更容易阅读。
弦#格式
格式化字符串最常用的方法是使用这个静态方法,它从Java 5开始就有了,有两个重载方法:
String#format(字符串格式,对象参数…) 字符串#格式(区域设置,字符串格式,对象参数…)
该方法易于使用,格式模式由底层格式化程序定义。
String step1 = "one";
String step2 = "two";
// results in "Step one of two"
String string = String.format("Step %s of %s", step1, step2);
您可以传递Locale以尊重语言和区域规范。更多信息请参考这个答案:https://stackoverflow.com/a/6431949/3764965 (Martin Törnwall)。
MessageFormat
MessageFormat类从Java的第一个版本开始就可用了,适合国际化。在最简单的形式中,有一个用于格式化的静态方法:
字符串模式,对象…参数)
String step1 = "one";
String step2 = "two";
// results in "Step one of two"
String string = MessageFormat.format("Step {0} of {1}", step1, step2);
记住,MessageFormat遵循与String#format不同的特定模式,更多细节请参阅它的JavaDoc: MessageFormat - patterns。
可以使用Locale,但是必须实例化类的对象并将其传递给构造函数,因为上面的静态方法使用带有默认Locale的默认构造函数。更多信息请参考这个答案:https://stackoverflow.com/a/6432100/3764965 (credit to taylor)。
非标准JDK解决方案
有很多方法可以使用外部库来格式化字符串。如果仅仅为了String格式化的目的而导入库,那么它们几乎没有任何好处。一些例子:
StringSubstitutor,在它的JavaDoc中的例子。 Cactoos: FormattedText,示例在这里。 有趣的是,Guava不打算添加格式或模板特性:#1142。 ... 和其他自定义实现。
您可以随意添加更多内容,但是,我认为没有理由进一步展开这一节。
Java 15以来的替代方案
有一个新的实例方法叫做string# formatting (Object…args)从Java 15开始。
内部实现与String#format(String format, Object…args)。
使用此字符串作为格式字符串的格式,以及提供的参数。
String step1 = "one";
String step2 = "two";
// results in "Step one of two"
String string = "Step %s of %s".formatted(step1, step2);
优点:不同之处在于该方法不是静态的,格式化模式本身是一个字符串,根据参数创建一个新的字符串。这允许链接首先构建格式本身。
缺点:Locale没有重载方法,因此使用默认方法。如果你需要使用自定义Locale,你必须坚持使用String#format(Locale l, String format, Object…args)。