Как использовать 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, который может быть полезен.

pr1001
источник
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, в документации вы увидите, что при необходимости можно изменить порядок аргументов по умолчанию. Однако, вероятно, единственный раз, когда вам понадобится / захочется это сделать, это если вы используете один и тот же аргумент более одного раза.

TM.
источник
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
OscarRyz
источник
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
PRO_gramista
источник
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
Shiv4nsh
источник