Вопрос-ответ

How to format strings in Java

Как форматировать строки в Java

Примитивный вопрос, но как мне форматировать строки подобным образом:


"Шаг {1} из {2}"


путем замены переменных с помощью Java? В C # это просто.

Переведено автоматически
Ответ 1

Взгляните на String.format. Однако обратите внимание, что для этого требуются спецификаторы формата, аналогичные спецификаторам семейства функций printf в C - например:

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

Вернет "Hello world, 42". Вы можете найти это полезным при изучении спецификаторов формата. Энди Томас-Крамер был достаточно любезен, чтобы оставить эту ссылку в комментарии ниже, которая, похоже, указывает на официальную спецификацию. Наиболее часто используемые из них::


  • %s - вставить строку

  • %d - вставить целое число со знаком (десятичное)

  • %f - вставить действительное число, стандартная запись

Это радикально отличается от C #, который использует позиционные ссылки с необязательным спецификатором формата. Это означает, что вы не можете делать такие вещи, как:

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

... фактически без повторения параметра, переданного в printf/format . (смотрите комментарий Scrum Meister ниже)


Если вы просто хотите распечатать результат напрямую, вы можете найти System.out.printf (PrintStream.printf) по своему вкусу.

Ответ 2

В дополнение к 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));

Более приятный пример использует преимущества улучшений varargs и автоматической упаковки в Java 1.5 и превращает вышеприведенное в однострочное:

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) });
Ответ 3

Новые возможности JDK

Приведенные ниже инструкции доступны начиная с Java 12+.

Шаблоны строк начиная с Java 21 (в качестве первого предварительного просмотра)

Представлен как JEP-460 (предварительный просмотр) в Java 21 и более поздних версиях как JEP-459 (Второй предварительный просмотр) в Java 22. API не является окончательным, и эта часть ответа может быть изменена.

Это усовершенствование предоставляет процессоры шаблонов для выполнения интерполяции строк.


  • STR статически импортируется неявно и немедленно интерполируется:
    int x = 10;
    int y = 20;
    // results in "10 + 20 = 30"
    String result = STR."\{x} + \{y} = \{x + y}";


  • RAW статический импорт должен быть выполнен явно, а интерполяция отменена:
    int x = 10;
    int y = 20;
    StringTemplate st = RAW."\{x} + \{y} = \{x + y}";
    ...
    // results in "10 + 20 = 30"
    String result = STR.process(st);


  • FMT комбинируется STR с Java Formatter:
    int x = 10;
    int y = 20;
    // results in "10 + 20 = 30.00"
    String result = FMT."%d\{x} + %d\{y} = %7.2f\{x + y}";


Альтернатива, начиная с 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. Это позволяет chaining сначала создать сам формат.

Недостаток: в Locale нет перегруженного метода, поэтому используется метод по умолчанию. Если вам нужно использовать пользовательский Locale, вы должны придерживаться String#format(Locale l, String format, Object... args).


Старые функции JDK

Приведенные ниже рекомендации были хорошо известны до появления Java 11, но остаются актуальными до сегодняшнего дня.

String#format

Наиболее распространенным способом форматирования строки является использование этого статического метода, который давно доступен, начиная с Java 5, и имеет два перегруженных метода:

Метод прост в использовании, а format шаблон определяется базовым средством форматирования.

String step1 = "one";
String step2 = "two";

// results in "Step one of two"
String string = String.format("Step %s of %s", step1, step2);

Вы можете передать Locale для соблюдения языковых и региональных спецификаций. Обратитесь к этому ответу для получения дополнительной информации: https://javalang.ru/a/6431949/3764965 (заслуги Мартина Тернуолла).

MessageFormat

Класс MessageFormat доступен с первой версии Java и подходит для интернационализации. В простейшей форме существует статический метод форматирования:

String step1 = "one";
String step2 = "two";

// results in "Step one of two"
String string = MessageFormat.format("Step {0} of {1}", step1, step2);

Помните, что MessageFormat следует определенному шаблону, отличному от String#format, обратитесь к его JavaDoc для получения более подробной информации: MessageFormat - patterns.

Можно использовать Locale, однако необходимо создать экземпляр объекта класса и передать его конструктору, поскольку статический метод, приведенный выше, использует конструктор по умолчанию с языковым стандартом по умолчанию. Обратитесь к этому ответу для получения дополнительной информации: https://javalang.ru/a/6432100/3764965 (заслуги ataylor).

StringBuilder и конкатенация строк

Они хорошо известны и описаны где-либо еще.


Решения, отличные от JDK

Существует множество способов форматирования строк с использованием внешних библиотек. Они практически не приносят пользы, если библиотеки импортируются исключительно для форматирования строк. Несколько примеров:


  • Apache Commons: StringSubstitutor, примеры в его JavaDoc.

  • Cactoos: FormattedText, примеры здесь.

  • Интересно, что Guava не планирует добавлять функции форматирования или создания шаблонов: #1142.

  • ... и другие пользовательские реализации.

Не стесняйтесь добавлять больше, однако я не нахожу причин для дальнейшего расширения этого раздела.

Ответ 4

Если вы решите не использовать String.format , другим вариантом будет бинарный оператор +

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

Это эквивалентно

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

Что бы вы ни использовали, выбирайте сами. StringBuilder быстрее, но разница в скорости незначительна. Я предпочитаю использовать + оператор (который выполняет a) StringBuilder.append(String.valueOf(X))) и считаю, что его легче читать.

java string