如何在 Scala 中使用 java.String.format?

Posted

技术标签:

【中文标题】如何在 Scala 中使用 java.String.format?【英文标题】:How to use java.String.format in Scala? 【发布时间】:2011-04-11 08:21:21 【问题描述】:

我正在尝试使用字符串的.format 方法。但是,如果我在字符串中放置 %1、%2 等,则会抛出 java.util.UnknownFormatConversionException,指向一个令人困惑的 Java 源代码片段:

private void checkText(String s) 

    int idx;

    // If there are any '%' in the given string, we got a bad format
    // specifier.
    if ((idx = s.indexOf('%')) != -1) 
        char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
        throw new UnknownFormatConversionException(String.valueOf(c));
    

据我所知,% char 是被禁止的。如果是这样,那么我应该为参数占位符使用什么?

我使用Scala 2.8。

【问题讨论】:

【参考方案1】:

在 Scala 2.10 中

val name = "Ivan"
val weather = "sunny"

s"Hello $name, it's $weather today!"

【讨论】:

我认为这只是字符串连接的一种特殊语法(意味着 $name 和 $weather 是对之前定义的变量的硬引用)。然而,String.Format 将模板作为参数,因此可以从属性文件等中检索模板。 - 上面的语法可以吗? 叫做字符串插值,在scala里面有s""和f""两种类型,'s'是简单的字符串,'f'类似于printf,你甚至可以定义自己的插值(我没有尝试过)。 $name 表示需要替换为变量name 的值,也可以在插值中进行操作,例如s"Hello $name.toUpperCase, it's $weather today!"【参考方案2】:

虽然前面的所有响应都是正确的,但它们都是 Java 语言。这是一个 Scala 示例:

val placeholder = "Hello %s, isn't %s cool?"
val formatted = placeholder.format("Ivan", "Scala")

我还有一篇关于 making format like Python's % operator 的博文可能有用。

【讨论】:

JDK 文档中的大量示例:docs.oracle.com/javase/7/docs/api/java/util/… 您可以通过将format 直接应用于字符串文字来简化:"Hello %s, isn't %s cool?".format("Ivan", "Scala")【参考方案3】:

在 scala 中,对于字符串插值,我们有 $ 可以节省时间并让我们的生活变得轻松:

例如:您想定义一个函数,该函数接受输入的姓名和年龄,然后说 Hello 用姓名和年龄。 可以这样写:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is $age"

因此,当你调用这个函数时:像这样:

funcStringInterpolationDemo("Shivansh",22)

它的输出是:

Hey ! my name is Shivansh and my age is 22

你可以在同一行编写代码来改变它,就像你想给年龄加 10 年一样!

那么函数可以是:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is $age+10"

现在输出将是:

Hey ! my name is Shivansh and my age is 32

【讨论】:

【参考方案4】:

虽然@Londo 提到了Scala 的“s”字符串插值器,但我认为Scala 的"f" string interpolator 与原始问题更相关。在其他响应中使用了几次的示例也可以这样编写(从 Scala 2.10 开始):

scala> val name = "Ivan"
name: String = Ivan
scala> val thing = "Scala"
thing: String = Scala
scala> val formatted = f"Hello $name%s, isn't $thing%s cool?"
formatted: String = Hello Ivan, isn't Scala cool?

与原始问题的联系是要注意:

formatted 使用前缀为字母“f”的字符串定义。这是“f”(格式化)字符串插值器。 “f”字符串插值器使用java.util.Formatter java.lang.String.format 使用相同的 java.util.Formatter

字符串插值的好处在于它可以让您看到哪个变量被直接替换到字符串中,而不必将其与String.format 方法的参数匹配。

【讨论】:

【参考方案5】:

这是String.format 可以做什么的列表。 printf也是如此

int i = 123;
o.printf( "|%d|%d|%n" ,       i, -i );      // |123|-123|
o.printf( "|%5d|%5d|%n" ,     i, -i );      // |  123| –123|
o.printf( "|%-5d|%-5d|%n" ,   i, -i );      // |123  |-123 |
o.printf( "|%+-5d|%+-5d|%n" , i, -i );      // |+123 |-123 |
o.printf( "|%05d|%05d|%n%n",  i, -i );      // |00123|-0123|

o.printf( "|%X|%x|%n", 0xabc, 0xabc );      // |ABC|abc|
o.printf( "|%04x|%#x|%n%n", 0xabc, 0xabc ); // |0abc|0xabc|

double d = 12345.678;
o.printf( "|%f|%f|%n" ,         d, -d );    // |12345,678000|     |-12345,678000|
o.printf( "|%+f|%+f|%n" ,       d, -d );    // |+12345,678000| |-12345,678000|
o.printf( "|% f|% f|%n" ,       d, -d );    // | 12345,678000| |-12345,678000|
o.printf( "|%.2f|%.2f|%n" ,     d, -d );    // |12345,68| |-12345,68|
o.printf( "|%,.2f|%,.2f|%n" ,   d, -d );    // |12.345,68| |-12.345,68|
o.printf( "|%.2f|%(.2f|%n",     d, -d );    // |12345,68| |(12345,68)|
o.printf( "|%10.2f|%10.2f|%n" , d, -d );    // |  12345,68| | –12345,68|
o.printf( "|%010.2f|%010.2f|%n",d, -d );    // |0012345,68| |-012345,68|

String s = "Monsterbacke";
o.printf( "%n|%s|%n", s );                  // |Monsterbacke|
o.printf( "|%S|%n", s );                    // |MONSTERBACKE|
o.printf( "|%20s|%n", s );                  // |        Monsterbacke|
o.printf( "|%-20s|%n", s );                 // |Monsterbacke        |
o.printf( "|%7s|%n", s );                   // |Monsterbacke|
o.printf( "|%.7s|%n", s );                  // |Monster|
o.printf( "|%20.7s|%n", s );                // |             Monster|

Date t = new Date();
o.printf( "%tT%n", t );                     // 11:01:39
o.printf( "%tD%n", t );                     // 04/18/08
o.printf( "%1$te. %1$tb%n", t );            // 18. Apr

【讨论】:

【参考方案6】:

官方参考是Formatter类。

【讨论】:

【参考方案7】:

您应该阅读 javadoc String.format() 和 Formatter syntax,而不是查看源代码。

在 % 之后指定值的格式。例如十进制整数是d,对于字符串是s

String aString = "world";
int aInt = 20;
String.format("Hello, %s on line %d",  aString, aInt );

输出:

Hello, world on line 20

要执行您尝试的操作(使用参数索引),请使用:*n*$

String.format("Line:%2$d. Value:%1$s. Result: Hello %1$s at line %2$d", aString, aInt );

输出:

Line:20. Value:world. Result: Hello world at line 20

【讨论】:

【参考方案8】:

您不需要使用数字来表示定位。默认情况下,参数的位置只是它在字符串中出现的顺序。

这是一个正确使用方法的示例:

String result = String.format("The format method is %s!", "great");
// result now equals  "The format method is great!".

您将始终使用% 后跟一些其他字符来让方法知道它应该如何显示字符串。 %s 可能是最常见的,它只是意味着应该将参数视为字符串。

我不会列出所有选项,但我会举几个例子来给你一个想法:

// we can specify the # of decimals we want to show for a floating point:
String result = String.format("10 / 3 = %.2f", 10.0 / 3.0);
// result now equals  "10 / 3 = 3.33"

// we can add commas to long numbers:
result = String.format("Today we processed %,d transactions.", 1000000);
// result now equals  "Today we processed 1,000,000 transactions."

String.format 仅使用java.util.Formatter,因此有关选项的完整说明,您可以查看Formatter javadocs。

而且,正如 BalusC 所提到的,您将在文档中看到可以根据需要更改默认参数顺序。但是,您唯一需要/想要这样做的可能是您多次使用相同的参数。

【讨论】:

【参考方案9】:

你可以用这个;

String.format("%1$s %2$s %2$s %3$s", "a", "b", "c");

输出:

a b b c

【讨论】:

没见过这种用法,重复字符串的时候很有用,棒棒哒! +1 这更像是您作为 C# 开发人员使用的东西。在那里,我们使用01 而不是%1$%2$ @ashes999 我也来自 c# 领域。我已经习惯了编号括号,我忘记了这不是标准的做事方式。看到百分号,一切都回来了!【参考方案10】:

这是与 String.format() 一起使用的格式化程序列表

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html

【讨论】:

【参考方案11】:

还请注意,Scala 使用多种方法扩展 String(通过隐式转换为 Predef 引入的 WrappedString),因此您还可以执行以下操作:

val formattedString = "Hello %s, isn't %s cool?".format("Ivan", "Scala")

【讨论】:

以上是关于如何在 Scala 中使用 java.String.format?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Pyspark 中使用 Scala 函数?

SORM:如何在 Scala 2.11.6 中使用 Sorm

如何在 Spark/Scala 中使用 countDistinct?

如何在 Java 中使用 Scala 隐式类

如何在 Java 中使用 Scala 隐式类

如何在 Databricks 的 PySpark 中使用在 Scala 中创建的 DataFrame