kat*_*tit 169 java string string-formatting
原始问题,但我如何格式化这样的字符串:
"{2}的步骤{1}"
通过使用Java替换变量?在C#中很容易.
Mar*_*all 217
看看String.format.但是请注意,它需要格式说明符类似于C的printf函数族 - 例如:
String.format("Hello %s, %d", "world", 42);
Run Code Online (Sandbox Code Playgroud)
将返回"Hello world,42".在了解格式说明符时,您可能会发现这很有用.Andy Thomas-Cramer非常友好地在下面的评论中留下这个链接,这似乎指向官方规范.最常用的是:
这与C#完全不同,后者使用带有可选格式说明符的位置引用.这意味着你不能做以下事情:
String.format("The {0} is repeated again: {0}", "word");
Run Code Online (Sandbox Code Playgroud)
... 没有实际重复传递给printf/format的参数.(参见Scrum Meister的评论如下)
如果您只想直接打印结果,可以根据自己的喜好找到System.out.printf(PrintStream.printf).
ata*_*lor 136
除了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));
Run Code Online (Sandbox Code Playgroud)
一个更好的例子利用了Java 1.5中的varargs和autoboxing改进,并将上述内容转化为单行:
MessageFormat.format("String is \"{1}\", number is {0}.", 42, "foobar");
Run Code Online (Sandbox Code Playgroud)
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) });
Run Code Online (Sandbox Code Playgroud)
我为它写了一个简单的方法:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
所以你可以用它作为:
SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");
Run Code Online (Sandbox Code Playgroud)
如果选择不使用String.format,则另一个选项是+二进制运算符
String str = "Step " + a + " of " + b;
Run Code Online (Sandbox Code Playgroud)
这相当于
new StringBuilder("Step ").append(String.valueOf(1)).append(" of ").append(String.valueOf(2));
您选择使用哪种。StringBuilder更快,但速度差异很小。我更喜欢使用+运算符(执行a StringBuilder.append(String.valueOf(X)))并发现它更易于阅读。
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("================================");
}
}
Run Code Online (Sandbox Code Playgroud)
outpot"================================"
ved15space123 ved15space123 ved15space123"=========== =====================
Java解决方案
" - "用于左缩进
"15"使String的最小长度为15
String::formatted(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);
Run Code Online (Sandbox Code Playgroud)
优点:不同之处在于该方法不是static,并且格式化模式是一个字符串本身,基于args. 这允许链接首先构建格式本身。
缺点: 没有重载方法Locale,因此使用默认方法。如果您需要使用自定义Locale,则必须坚持使用String::format(Locale l,String format,Object... args).
您可以使用 Java 的字符串模板功能。它在JEP 430中进行了描述,并作为预览功能出现在 JDK 21 中。
这是一个使用示例:
String name = "Joan";
String info = STR."My name is \{name}";
assert info.equals("My name is Joan"); // true
Run Code Online (Sandbox Code Playgroud)
与其他语言(例如 C# 的字符串插值和 Python 的 f 字符串)中的功能相比,Java 的字符串模板更加通用且安全得多。例如,字符串连接或插值使得 SQL 注入攻击成为可能:
String query = "SELECT * FROM Person p WHERE p.last_name = '" + name + "'";
ResultSet rs = conn.createStatement().executeQuery(query);
Run Code Online (Sandbox Code Playgroud)
但这个变体(来自 JEP 430)可以防止 SQL 注入:
PreparedStatement ps = DB."SELECT * FROM Person p WHERE p.last_name = \{name}";
ResultSet rs = ps.executeQuery();
Run Code Online (Sandbox Code Playgroud)