No Python, ao formatar a string, posso preencher espaços reservados por nome e não por posição, assim:
print "There's an incorrect value '%(value)s' in column # %(column)d" % \
{ 'value': x, 'column': y }
Gostaria de saber se isso é possível em Java (espero, sem bibliotecas externas)?
java
string-formatting
Andy
fonte
fonte
%s
era prática comum. pt.wikipedia.org/wiki/Printf_format_string#History Observe também que alguns IDE e FindBugs podem detectar automaticamente contagens% s e% d incompatíveis, mas eu ainda preferiria os campos nomeados.Respostas:
O StrSubstitutor de jakarta commons lang é uma maneira leve de fazer isso, desde que seus valores já estejam formatados corretamente.
http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/text/StrSubstitutor.html
O resultado acima resulta em:
"Existe um valor incorreto '1' na coluna # 2"
Ao usar o Maven, você pode adicionar essa dependência ao seu pom.xml:
fonte
${arg}
) em vez da personalizada acima (%(arg)
), o regex não será compilado, o que é o efeito desejado.não é bem assim, mas você pode usar o MessageFormat para referenciar um valor várias vezes:
O exemplo acima também pode ser feito com String.format (), mas acho a sintaxe messageFormat mais limpa, se você precisar criar expressões complexas, além de não precisar se preocupar com o tipo de objeto que está colocando na string
fonte
MessageFormat
é grande, mas pesado para relativamente grande conteúdo jsonOutro exemplo do Apache Common StringSubstitutor para um espaço reservado simples nomeado.
fonte
replaceIn
quais valores substitutos em um buffer: StringBuilder ou TextStringBuilder. Com essa abordagem, todo o conteúdo do arquivo não será carregado na memória.Você pode usar a biblioteca StringTemplate , ela oferece o que você deseja e muito mais.
fonte
'
caractere:unexpected char: '''
Para casos muito simples, você pode simplesmente usar uma substituição de String codificada, sem a necessidade de uma biblioteca:
AVISO : Eu só queria mostrar o código mais simples possível. Obviamente, NÃO use isso para código de produção sério, onde a segurança é importante, conforme declarado nos comentários: escape, manipulação de erros e segurança são um problema aqui. Mas no pior dos casos, agora você sabe por que é necessário usar uma lib 'boa' :-)
fonte
Obrigado por toda sua ajuda! Usando todas as suas pistas, escrevi uma rotina para fazer exatamente o que eu quero - formatação de string semelhante a python usando dicionário. Desde que eu sou novato em Java, todas as dicas são bem-vindas.
fonte
formatPos
não pode conterformatKey
.Este é um encadeamento antigo, mas apenas para constar, você também pode usar o estilo Java 8, assim:
Uso:
A saída será:
fonte
.reduce()
resultados da substituição intermediária são tratados como cadeias de formato próprias, esta solução é vulnerável a ataques de cadeia de formatação . Qualquer solução correta deve fazer uma única passagem pela string de formato.Exemplo:
fonte
.replaceAll()
retornos de chamada de substituição de cadeia .Eu sou o autor de uma pequena biblioteca que faz exatamente o que você deseja:
Ou você pode encadear os argumentos:
fonte
O método replaceEach do Apache Commons Lang pode ser útil dependendo de suas necessidades específicas. Você pode usá-lo facilmente para substituir espaços reservados pelo nome com esta única chamada de método:
Dado algum texto de entrada, isso substituirá todas as ocorrências dos espaços reservados na primeira matriz de string pelos valores correspondentes na segunda.
fonte
Você pode ter algo assim em uma classe auxiliar de string
fonte
Minha resposta é:
a) use StringBuilder quando possível
b) mantenha (em qualquer forma: número inteiro é o melhor, caracteres especiais como macro de dólar etc.) posição de "espaço reservado" e use
StringBuilder.insert()
(poucas versões de argumentos).O uso de bibliotecas externas parece um exagero e acredito degradar o desempenho de maneira significativa, quando StringBuilder é convertido em String internamente.
fonte
Com base na resposta que criei
MapBuilder
classe:então eu criei a classe
StringFormat
para formatação de String:que você pode usar assim:
fonte
Criei também uma classe util / helper (usando o jdk 8) que pode formatar uma string e substituir ocorrências de variáveis.
Para esse propósito, usei o método "appendReplacement" do Matchers, que faz toda a substituição e faz loops apenas nas partes afetadas de uma string de formato.
Atualmente, a classe auxiliar não está bem documentada pelo javadoc. Vou mudar isso no futuro;) De qualquer forma, comentei as linhas mais importantes (espero).
Você pode criar uma instância de classe para um mapa específico com valores (ou prefixo de sufixo ou noKeyFunction) como:
Além disso, você pode definir o que acontece se uma chave no mapa de valores estiver ausente (funciona nos dois sentidos, por exemplo, nome incorreto da variável na string de formato ou chave ausente no mapa). O comportamento padrão é uma exceção não verificada lançada (desmarcada porque eu uso a função jdk8 padrão que não pode lidar com exceções verificadas) como:
Você pode definir um comportamento customizado na chamada do construtor, como:
ou delegá-lo de volta ao comportamento padrão sem chave:
Para um melhor manuseio, também existem representações estáticas de métodos, como:
fonte
Não há nada incorporado ao Java no momento de escrever isso. Eu sugeriria escrever sua própria implementação. Minha preferência é por uma interface simples de construtor fluente, em vez de criar um mapa e passá-lo para funcionar - você acaba com um bom pedaço de código contíguo, por exemplo:
Aqui está uma implementação simples:
fonte
Experimente o Freemarker , biblioteca de modelos.
fonte
https://dzone.com/articles/java-string-format-examples String.format (inputString, [listOfParams]) seria a maneira mais fácil. Os espaços reservados na sequência podem ser definidos por ordem. Para mais detalhes, consulte o link fornecido.
fonte
Você deve dar uma olhada na biblioteca oficial do ICU4J . Ele fornece uma classe MessageFormat semelhante à disponível com o JDK, mas essa antiga suporta espaços reservados nomeados.
Ao contrário de outras soluções fornecidas nesta página. O ICU4j faz parte do projeto do ICU que é mantido pela IBM e atualizado regularmente. Além disso, ele suporta casos de uso avançados, como pluralização e muito mais.
Aqui está um exemplo de código:
fonte
Existe o Java Plugin para usar a interpolação de strings em Java (como no Kotlin, JavaScript). Suporte Java 8, 9, 10, 11 ... https://github.com/antkorwin/better-strings
Usando variáveis em literais de string:
Usando expressões:
Usando funções:
Para mais informações, leia o projeto README.
fonte