Как использовать java.String.format в Scala?


322

Я пытаюсь использовать .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));
    }
}

Из этого я понимаю, что %символ запрещен. Если так, то что я должен использовать для аргументов заполнителей?

Я использую Scala 2.8.

Ответы:


302

Хотя все предыдущие ответы верны, они все на Java. Вот пример Scala:

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

У меня также есть пост в блоге о том, formatкак сделать %оператор Python, который может быть полезен.


2
Много примеров в документации JDK: docs.oracle.com/javase/7/docs/api/java/util/…
— angelcervera

1
Вы можете упростить, применив formatнепосредственно к строковому "Hello %s, isn't %s cool?".format("Ivan", "Scala")
— литералу

298

Вам не нужно использовать цифры для обозначения позиционирования. По умолчанию позиция аргумента - это просто порядок, в котором он появляется в строке.

Вот пример правильного способа использовать это:

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, так что для полного описания параметров вы можете увидеть Javadocs Formatter .

И, как упоминает BalusC, в документации вы увидите, что при необходимости можно изменить порядок аргументов по умолчанию. Однако, вероятно, единственный раз, когда вам понадобится / захочется это сделать, это если вы используете один и тот же аргумент более одного раза.


127

Вместо того, чтобы смотреть на исходный код, вы должны прочитать синтаксис javadoc String.format () и Formatter .

Вы указываете формат значения после%. Например, для десятичного целого числа это так 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

70

Вы можете использовать это;

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

Вывод:

Аббв


1
Я никогда не видел такого рода использования, это очень полезно, когда повторяю строку, отлично!
— Доми.Жанг

8
+1 это больше похоже на то, что вы используете в качестве разработчика на C #. Там мы используем {0}и {1}вместо %1$и %2$.
— ashes999

@ ashes999 Я из c # земли, а также. Я так привык к пронумерованным скобкам, что забыл, что это не стандартный способ ведения дел. Видя знаки процента возвращает все это, хотя!
— JonnyRaa

13

Также обратите внимание, что Scala расширяет String рядом методов (посредством неявного преобразования в WrappedString, введенную Predef), поэтому вы также можете сделать следующее:

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


10

В Scala 2.10

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

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

1
Я полагаю, что это всего лишь специальный синтаксис конкатенации строк (это означает, что $ name и $ weather являются жесткими ссылками на переменные, определенные ранее). Однако String.Format принимает шаблон в качестве параметра и, таким образом, позволяет, например, получить шаблон из файла свойств и тому подобного. - Возможно ли это с приведенным выше синтаксисом?
— Чиккодоро

Это интерполяция с вызовом строки, в Scala есть два типа: s "" и f "", s - простая строка, а f - аналогично printf, вы даже можете определить свою собственную интерполяцию (у меня нет пытаться). Это $nameозначает, что его необходимо заменить значением переменной name, вы также можете выполнить операцию в интерполяции, напримерs"Hello ${name.toUpperCase}, it's $weather today!"
— Londo

3

Это список того, что 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


1

Хотя @Londo упомянул строковый интерполятор Scala «s», я думаю, что строковый интерполятор Scala «f» больше относится к исходному вопросу. Пример, использованный несколько раз в других ответах, также может быть записан (начиная с 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метода.


0

В 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.