Java 字符串格式中的自动字段编号
我正在尝试使用Java 字符串格式中的自动字段编号,java,Java,我正在尝试使用MessageFormatclass在java中格式化字符串。字符串包含位置字段,但仅当我提供字段编号时才起作用。例如 MessageFormat.format(“{0}{1}”,“Hi”,“Java”) MessageFormat.format(“{}{}”,“Hi”,“Java”) Exception in thread "main" java.lang.IllegalArgumentException: can't parse argument number: at
MessageFormat
class在java中格式化字符串。字符串包含位置字段,但仅当我提供字段编号时才起作用。例如
MessageFormat.format(“{0}{1}”,“Hi”,“Java”)
MessageFormat.format(“{}{}”,“Hi”,“Java”)
Exception in thread "main" java.lang.IllegalArgumentException: can't parse argument number:
at java.text.MessageFormat.makeFormat(MessageFormat.java:1429)
at java.text.MessageFormat.applyPattern(MessageFormat.java:479)
at java.text.MessageFormat.<init>(MessageFormat.java:362)
at java.text.MessageFormat.format(MessageFormat.java:840)
at controller.App.main(App.java:11)
Caused by: java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:592)
at java.lang.Integer.parseInt(Integer.java:615)
at java.text.MessageFormat.makeFormat(MessageFormat.java:1427)
听起来这就是你要找的
String foo = String.format("%s %s", "Hi", "Java")
StringBuffer bar = new StringBuffer(foo);
您可以执行以下黑客操作:
String.format("{} {}".replace("{}", "%s"), new String[]{"Hi", "Java"}));
它首先将{}
替换为%s
,然后将每个%s
替换为作为方法参数提供的字符串数组中的相应值
请注意,由于格式
接受对象。。。args
作为第二个参数,您可以编写:
String.format("{} {}".replace("{}", "%s"), "Hi", "Java");
我使用slf4j进行日志记录,这样可以记录如下字符串:
LoggerFactory.getLogger("name").debug("{} {}", "Hello", "World");
只需看一看源代码,就知道它是如何格式化字符串的,它使用了以下类:
org.slf4j.helpers.MessageFormatter
这里有3种方法。1替换单个对象时:
MessageFormatter.format(String message, Object arg);
一个替换为两个对象:
MessageFormatter.format(String message, Object arg1, Object arg2);
其中一个用于替换对象数组:
MessageFormatter.arrayFormat(String message, Object[] argArray);
它们都返回类型为FormattingTuple
的对象。要从对象获取格式化字符串,应调用FormattingTuple.getMessage()代码>
要与手动字段编号一起使用,请查看以下方法:
public String formatString(String original, Object... replacements) {
String stringToReturn = original;
for (int i = 0; i < replacements.length; i++) {
stringToReturn = stringToReturn.replaceAll("\\{" + i + "\\}", replacements[i].toString());
}
return MessageFormatter.arrayFormat(stringToReturn, replacements).getMessage();
}
公共字符串格式字符串(字符串原始、对象…替换){
字符串stringToReturn=原始字符串;
for(int i=0;i
添加到@JohnH answer,String.format可以为格式化字符串执行自动和手动字段索引
String.format("%s %s", "Hi", "Java")
String.format("%1$s %2$s %1$s", "Hi", "Java")
这比不上“{1}{2}”
更符合人体工程学,但它完成了任务。如果我被限制在Barunthakur这样的标准库中,我会使用Maroun Maroun发布的模式
Ben Greens聪明的想法对于使用非索引参数登录时使用sfl4j的每个人都很有用,此外,还可以使用索引参数手动准备字符串
我有一个缺点:
我现在可以使用索引参数和非索引参数,但无法使用java.text.MessageFormat.format()中的FormatType和FormatStyle选项,例如{0,number,currency}
因此,我制定了本解决方案的扩展版本,它利用了所有3种变体
import org.slf4j.helpers.MessageFormatter;
import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static String format(String original, Object... replacements)
{
if (Pattern.matches(".*\\{\\d+,.+,.+\\}.*", original))
{
return MessageFormat.format(original, replacements);
}
else
{
String r = "\\{\\d\\}";
if(original.matches(".*" + r + ".*"))
{
Pattern p = Pattern.compile(r);
Matcher m = p.matcher(original);
StringBuffer b = null;
int i = 0;
while(m.find())
{
if(b == null) b = new StringBuffer();
m.appendReplacement(b, replacements[i].toString());
i++;
}
m.appendTail(b);
return (i > 0) ? b.toString() : null;
}
else
{
return MessageFormatter.arrayFormat(original, replacements).getMessage();
}
}
}
单元测试:
String expected = "pink is a disgusting color";
String actual = StringHelpers.format("{0} is a disgusting {1}", "pink", "color");
assertEquals(expected, actual);
expected = "01-02-2017 was a rather meh day";
actual = StringHelpers.format("{0,date,MM-dd-YYYY} was a rather {1} day", new Date(117,0,2), "meh");
assertEquals(expected, actual);
expected = "One Person expects the danish inquisition";
actual = StringHelpers.format("{} expects the {} inquisition", "One Person", "danish");
assertEquals(expected, actual);
如果您不想提供索引,那么请使用String.format
。是的,我可以这样做,但有一个用例,我可以获得带或不带索引的字符串。是的,这将起作用,但不是我想要的。此外,这对参数的位置索引也没有帮助。@baruntshakur您必须检查需要使用哪个版本。请为此尝试一个正则表达式。System.out.println(MessageFormatter.format(“{1}{2}{1}”,“hi”,“java”).getMessage()
输出{1}{2}{1}
。您的问题表明您希望在不指定位置字段的情况下执行此操作<代码>System.out.println(MessageFormatter.format(“{}{}”,“hi”,“java”).getMessage())
outputshi java
No.“它可以处理自动和手动字段编号”刚刚用我编写的一个快速方法编辑了我的答案,以处理这两种情况。是的,这可以工作,但这是一个解决方法,我想要的是一个标准库或做它的东西。
String expected = "pink is a disgusting color";
String actual = StringHelpers.format("{0} is a disgusting {1}", "pink", "color");
assertEquals(expected, actual);
expected = "01-02-2017 was a rather meh day";
actual = StringHelpers.format("{0,date,MM-dd-YYYY} was a rather {1} day", new Date(117,0,2), "meh");
assertEquals(expected, actual);
expected = "One Person expects the danish inquisition";
actual = StringHelpers.format("{} expects the {} inquisition", "One Person", "danish");
assertEquals(expected, actual);