如何在Java中格式化字符串

时间:2011-06-21 21:02:43

标签: java string string-formatting

原始问题,但我如何格式化这样的字符串:

  

“{2}的步骤{1}”

用Java替换变量?在C#中很容易。

10 个答案:

答案 0 :(得分:204)

看看String.format。但请注意,格式说明符与C的printf函数族类似 - 例如:

String.format("Hello %s, %d", "world", 42);

将返回“Hello world,42”。在了解格式说明符时,您可能会发现this很有帮助。 Andy Thomas-Cramer非常友好地在下面的评论中留下this链接,这似乎指向了官方规范。最常用的是:

  • %s - 插入字符串
  • %d - 插入有符号整数(十进制)
  • %f - 插入实数,标准符号

这与C#截然不同,后者使用带有可选格式说明符的位置引用。 这意味着您无法执行以下操作:

String.format("The {0} is repeated again: {0}", "word");

... 没有实际重复传递给printf / format的参数。(参见下面的Scrum Meister评论)


如果您只想直接打印结果,可以根据自己的喜好找到System.out.printf(PrintStream.printf)。

答案 1 :(得分:127)

除了String.format之外,还要看一下java.text.MessageFormat。格式更简洁,更接近您提供的C#示例,您也可以使用它进行解析。

例如:

int someNumber = 42;
String someString = "foobar";
Object[] args = {new Long(someNumber), someString};
MessageFormat fmt = new MessageFormat("String is \"{1}\", number is {0}.");
System.out.println(fmt.format(args));

一个更好的例子利用了Java 1.5中的varargs和autoboxing改进,并将上述内容转化为单行:

MessageFormat.format("String is \"{1}\", number is {0}.", 42, "foobar");

MessageFormat使用选择修饰符进行i18nized复数更好一点。要指定在变量为1时正确使用单数形式的消息,否则为多数,您可以执行以下操作:

String formatString = "there were {0} {0,choice,0#objects|1#object|1<objects}";
MessageFormat fmt = new MessageFormat(formatString);
fmt.format(new Object[] { new Long(numberOfObjects) });

答案 2 :(得分:6)

我为它写了一个简单的方法:

public class SomeCommons {
    /** Message Format like 'Some String {0} / {1}' with arguments */
    public static String msgFormat(String s, Object... args) {
        return new MessageFormat(s).format(args);
    }
}

所以你可以用它作为:

SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");

答案 3 :(得分:5)

public class StringFormat {

    public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            System.out.println("================================");
            for(int i=0;i<3;i++){
                String s1=sc.next();
                int x=sc.nextInt();
                System.out.println(String.format("%-15s%03d",s1,x));
            }
            System.out.println("================================");

    }
}
  

outpot   “================================”
  ved15space123   ved15space123   ved15space123   “================================

Java解决方案

  • “ - ”用于左缩进

  • “15”使字符串的最小长度为15

  • “s”(%之后的几个字符)将被我们的字符串
  • 取代
  • 0填充我们的整数,左边是0
  • 3使我们的整数最小长度为3

答案 4 :(得分:3)

如果您选择不使用String.format,则另一个选项是+二元运算符

String str = "Step " + a + " of " + b;

这相当于

new StringBuilder("Step ").append(String.valueOf(1)).append(" of ").append(String.valueOf(2));

无论您使用哪种方式,都是您的选择。 StringBuilder更快,但速度差异很小。我更喜欢使用+运算符(执行StringBuilder.append(String.valueOf(X)))并更容易阅读。

答案 5 :(得分:2)

Java 15

从Java 15开始,有一个名为String::formatted(Object... args)的新实例方法。

内部实现与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);     

优点:不同之处在于该方法不是static,格式化模式是字符串本身,根据该字符串将创建一个新字符串args。这允许链接首先构建格式本身。

缺点Locale没有重载方法,因此使用默认方法。如果您需要使用自定义Locale,则必须坚持使用String::format(Locale l,String format,Object... args)

答案 6 :(得分:1)

这个解决方案对我有用。我需要动态创建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 /顺序”

答案 7 :(得分:0)

我写了这个函数,它做对了。插入一个以$开头的单词,并带有相同名称的变量的值。

private static String interpol1(String x){
    Field[] ffield =  Main.class.getDeclaredFields();
    String[] test = x.split(" ") ;
    for (String v : test ) {
        for ( Field n: ffield ) {
            if(v.startsWith("$") && ( n.getName().equals(v.substring(1))  )){
                try {
                    x = x.replace("$" + v.substring(1), String.valueOf( n.get(null)));
                }catch (Exception e){
                    System.out.println("");
                }
            }
        }
    }
    return x;
}

答案 8 :(得分:0)

Apache Commons Text中的org.apache.commons.text.StringSubstitutor帮助类提供了命名变量替换

Map<String, String> valuesMap = new HashMap<>();
valuesMap.put("animal", "quick brown fox");
valuesMap.put("target", "lazy dog");
String resolved = new StringSubstitutor(valuesMap).replace("The ${animal} jumped over the ${target}.");
System.out.println(resolved); // The quick brown fox jumped over the lazy dog.

答案 9 :(得分:0)

Apache Commons StringSubstitutor 提供了一种简单易读的方式来使用命名变量格式化 String

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"