Como formatar cadeias de caracteres em Java

Respostas:

140

Além de String.format, também dê uma olhada java.text.MessageFormat. O formato menos conciso e um pouco mais próximo do exemplo de C # que você forneceu e pode ser usado para analisar também.

Por exemplo:

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));

Um exemplo melhor aproveita os aprimoramentos de varargs e autoboxing no Java 1.5 e transforma o anterior em uma linha:

MessageFormat.format("String is \"{1}\", number is {0}.", 42, "foobar");

MessageFormaté um pouco melhor para fazer plurais i18nizados com o modificador de escolha. Para especificar uma mensagem que use corretamente a forma singular quando uma variável for 1 e plural, caso contrário, você poderá fazer algo assim:

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) });
ataylor
fonte
21
MessageFormat é para fins de localização, portanto, tome cuidado ao usá-lo. Por exemplo, o código a seguir, MessageFormat.format("Number {0}", 1234));dependendo da localidade padrão, pode produzir em Number 1,234vez de Number 1234.
pavel_kazlou
@ataylor: Olá, desculpe, mas estou um pouco confuso. Eu quero algo assim, passarei o objeto Class que possui dados e quando {0} it ll take firstname, quando {1} then lastname, assim. É possível {0,choice,0.getFirstName()}ou algo assim?
precisa saber é o seguinte
@ user3145373 ツ Acho que não.
ataylor
Ok, tudo bem, eu me referi a um projeto .Net como eu quero, codeproject.com/Articles/42310/… , consulte este projeto e estou parecendo assim. Se você conhece algum projeto ou pacote disponível assim, informe-me. Obrigado, usuário
user3145373 #
233

Dê uma olhada no String.format . Observe, no entanto, que são necessários especificadores de formato semelhantes aos da família de funções printf de C - por exemplo:

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

Gostaria de retornar "Olá mundo, 42". Você pode achar isso útil ao aprender sobre os especificadores de formato. Andy Thomas-Cramer teve a gentileza de deixar esse link em um comentário abaixo, o que parece apontar para as especificações oficiais. Os mais usados ​​são:

  • % s - insere uma string
  • % d - insere um número inteiro assinado (decimal)
  • % f - insere um número real, notação padrão

Isso é radicalmente diferente do C #, que usa referências posicionais com um especificador de formato opcional. Isso significa que você não pode fazer coisas como:

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

... sem realmente repetir o parâmetro passado para printf / format. (veja o comentário do The Scrum Meister abaixo)


Se você quiser apenas imprimir o resultado diretamente, poderá encontrar System.out.printf ( PrintStream.printf ) ao seu gosto.

Martin Törnwall
fonte
2
Outra opção é java.text.MessageFormat, que aceita os símbolos de formato de estilo {1}. Os símbolos de formato de String.format () podem ser semelhantes aos símbolos de formato printf () de C - mas também podem diferir. Consulte download.oracle.com/javase/6/docs/api/java/util/… para obter a sintaxe completa.
Andy Thomas
53
String.formattambém pode assumir posições numéricas: String.format("%2$s %1$s", "foo", "bar");será exibidobar foo
The Scrum Meister
7

Se você optar por não usar String.format, a outra opção é o operador binário +

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

Isso é equivalente a

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

O que você usar é a sua escolha. StringBuilder é mais rápido, mas a diferença de velocidade é marginal. Prefiro usar o +operador (que faz um StringBuilder.append(String.valueOf(X)))e acha mais fácil ler.

Ryan Amos
fonte
5
Se você vai me negar, explique por que.
Ryan Amos
11
1) Em resposta a uma pergunta sobre formatação de string, você explica como o +operador funciona. 2) Sua explicação não é precisa. +é equivalente a usar StringBuilder, não String.concat. (Way muita informação sobre isso.)
Søren Løvborg
6

Eu escrevi meu método simples para isso:

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);
    }
}

para que você possa usá-lo como:

SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");
Tomasz Modelski
fonte
5
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("================================");

    }
}

outpot "================================"
ved15space123 ved15space123 ved15space123 "=========== =======================

Solução Java

  • O "-" é usado para recuar à esquerda

  • O "15" faz com que o comprimento mínimo da String seja de 15

  • O "s" (que é alguns caracteres após%) será substituído por nossa String
  • O 0 preenche nosso número inteiro com 0s à esquerda
  • O 3 faz nosso número inteiro ter um comprimento mínimo de 3
Ved Prakash
fonte
1
Você está certo docs.oracle.com/javase/8/docs/api/java/util/…
ℛɑƒæĿᴿᴹᴿ
1

Esta solução funcionou para mim. Eu precisava criar URLs para um cliente REST dinamicamente, então criei esse método, então você só precisa passar o restURL assim

/customer/{0}/user/{1}/order

e adicione quantos parâmetros você precisar:

public String createURL (String restURL, Object ... params) {       
    return new MessageFormat(restURL).format(params);
}

Você apenas precisa chamar esse método assim:

createURL("/customer/{0}/user/{1}/order", 123, 321);

A saída

"/ customer / 123 / user / 321 / order"

Felipe Bejarano
fonte
0

Eu escrevi essa função que faz a coisa certa. Interpole uma palavra começando com $o valor da variável com o mesmo nome.

private static String interpol1(String x){
    Field[] ffield =  Main.class.getDeclaredFields();
    String[] test = x.split(" ") ;
    for (String v : test ) {
        for ( Field n: ffield ) {
            if(v.startsWith("$") && ( n.getName().equals(v.substring(1))  )){
                try {
                    x = x.replace("$" + v.substring(1), String.valueOf( n.get(null)));
                }catch (Exception e){
                    System.out.println("");
                }
            }
        }
    }
    return x;
}
DefconT34
fonte