Estou procurando um bom equivalente em JavaScript do C / PHP printf()
ou para programadores de C # / Java String.Format()
( IFormatProvider
para .NET).
Meu requisito básico é um formato separador de milhar para números por enquanto, mas algo que lide com muitas combinações (incluindo datas) seria bom.
Sei que a biblioteca Ajax da Microsoft fornece uma versão do String.Format()
, mas não queremos toda a sobrecarga dessa estrutura.
javascript
printf
string.format
Chris S
fonte
fonte
Respostas:
A partir do ES6, você pode usar seqüências de caracteres de modelo:
Veja a resposta de Kim abaixo para obter detalhes.
De outra forma:
Experimente sprintf () para JavaScript .
Se você realmente deseja fazer um método de formato simples por conta própria, não faça as substituições sucessivamente, mas faça-as simultaneamente.
Como a maioria das outras propostas mencionadas falha quando uma string de substituição anterior também contém uma sequência de formatos como esta:
Normalmente você esperaria que a saída fosse,
{1}{0}
mas a saída real é{1}{1}
. O mesmo acontece com uma substituição simultânea, como na sugestão de medo de ser destruída .fonte
num.toFixed()
método pode ser suficiente!sprintf() for JavaScript
não estava disponível.underscore.string
possui mais recursos além do sprintf, que é baseado nasprintf() for JavaScript
implementação. Fora isso, a biblioteca é um projeto totalmente diferente.Com base nas soluções sugeridas anteriormente:
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
saídas
Se você preferir não modificar
String
o protótipo:Dá a você muito mais familiar:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
com o mesmo resultado:
fonte
+
operador-), certifique-se de colocar a String completa entre parênteses:("asd {0}"+"fas {1}").format("first", "second");
caso contrário, a função será aplicada apenas à última string que foi anexada.'foo {0}'.format(fnWithNoReturnValue())
. No momento, ele retornariafoo {0}
. Com suas alterações, ele retornariafoo undefined
.É engraçado porque o Stack Overflow realmente tem sua própria função de formatação para o
String
protótipo chamadoformatUnicorn
. Tente! Entre no console e digite algo como:Você obtém esta saída:
Hello, Gabriel, are you feeling OK?
Você pode usar objetos, matrizes e seqüências de caracteres como argumentos! Peguei o código e o reformulei para produzir uma nova versão do
String.prototype.format
:Observe a
Array.prototype.slice.call(arguments)
chamada inteligente - isso significa que, se você lançar argumentos que são seqüências de caracteres ou números, e não um único objeto no estilo JSON, obtém oString.Format
comportamento do C # quase exatamente.Isso porque
Array
'sslice
forçarão tudo o que está emarguments
em umArray
, se era originalmente ou não, ekey
será o índice (0, 1, 2 ...) de cada elemento da matriz coagidos a uma string (por exemplo, '0', de modo"\\{0\\}"
para seu primeiro padrão de expressão regular).Arrumado.
fonte
g
), que pode substituir a mesma chave mais de uma vez. No exemplo acima, você pode usar{name}
várias vezes na mesma frase e substituí-las todas.name
é"blah {adjective} blah"
?Formatação de números em JavaScript
Cheguei a esta página de perguntas na esperança de descobrir como formatar números em JavaScript, sem introduzir outra biblioteca. Aqui está o que eu encontrei:
Arredondando números de ponto flutuante
O equivalente
sprintf("%.2f", num)
em JavaScript parece sernum.toFixed(2)
, que formatanum
duas casas decimais, com arredondamento (mas consulte o comentário de @ ars265 sobreMath.round
abaixo).Forma exponencial
O equivalente a
sprintf("%.2e", num)
énum.toExponential(2)
.Bases hexadecimais e outras
Para imprimir números na base B, tente
num.toString(B)
. O JavaScript suporta conversão automática de e para as bases 2 a 36 (além disso, alguns navegadores têm suporte limitado à codificação base64 ).Páginas de referência
Tutorial rápido sobre formatação de número JS
Página de referência da Mozilla para toFixed () (com links para toPrecision (), toExponential (), toLocaleString (), ...)
fonte
..
também funciona:33333..toExponential(2);
A partir do ES6, você pode usar seqüências de caracteres de modelo :
Esteja ciente de que as seqüências de caracteres do modelo são cercadas por backticks `em vez de aspas simples.
Para mais informações:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Nota: Verifique o site do mozilla para encontrar uma lista de navegadores suportados.
fonte
const compile = (x, y) => `I can call this template string whenever I want.. x=${x}, y=${y}`
...compile(30, 20)
jsxt, Zippo
Esta opção se encaixa melhor.
Com esta opção eu posso substituir strings como estas:
Com o seu código, o segundo {0} não seria substituído. ;)
fonte
Eu uso esta função simples:
Isso é muito semelhante ao string.format:
fonte
+=
?, deveriaformatted = this.replace("{" + arg + "}", arguments[arg]);
for...in
não funcionará em todos os navegadores, como este código espera. Ele percorrerá todas as propriedades enumeráveis, que em alguns navegadores incluirãoarguments.length
e em outros nem sequer incluirão os próprios argumentos. De qualquer forma, seObject.prototype
for adicionado a, quaisquer acréscimos provavelmente serão incluídos no grupo. O código deve estar usando umfor
loop padrão , e nãofor...in
."{0} is dead, but {1} is alive!".format("{1}", "ASP.NET") === "ASP.NET is dead, but ASP.NET is alive!"
arg
é global. Você precisa fazer isso:for (var arg in arguments) {
Para usuários do Node.js, existe
util.format
uma funcionalidade semelhante à printf:fonte
%-20s %5.2f
)Estou surpreso que ninguém tenha usado
reduce
, esta é uma função JavaScript concisa e poderosa nativa.ES6 (EcmaScript2015)
<ES6
Como funciona:
fonte
printf
função simplificada : jsfiddle.net/11szrbx9(...a) => {return a.reduce((p: string, c: any) => p.replace(/%s/, c));
String.prototype.format
nos ES6:((a,b,c)=>`${a}, ${b} and ${c}`)(...['me', 'myself', 'I'])
(note que este é um pouco redundante para melhor ajuste no seu exemplo)printf
especificadores de tipo e incluir lógica para prefixos de preenchimento. Iterar sobre a sequência de formatação de maneira sensata parece ser o menor desafio aqui, imho. Solução elegante, se você só precisa de substituições de cordas.Aqui está uma implementação mínima do sprintf no JavaScript: ele faz apenas "% s" e "% d", mas deixei espaço para que ele fosse estendido. É inútil para o OP, mas outras pessoas que se deparam com esse segmento vindo do Google podem se beneficiar dele.
Exemplo:
Em contraste com soluções semelhantes nas respostas anteriores, esta realiza todas as substituições de uma só vez , portanto, não substituirá partes dos valores substituídos anteriormente.
fonte
Programadores JavaScript podem usar String.prototype.sprintf em https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js . Abaixo está um exemplo:
fonte
Adicionando à
zippoxer
resposta, eu uso esta função:Também tenho uma versão sem protótipo que uso com mais frequência para sua sintaxe semelhante a Java:
Atualização do ES 2015
Todo o material interessante do ES 2015 facilita muito isso:
Imaginei que, como essas, como as mais antigas, na verdade não analisam as letras, é melhor usar apenas um único token
%%
. Isso tem o benefício de ser óbvio e não dificultar o uso de um único%
. No entanto, se você precisar,%%
por algum motivo, precisará substituí-lo por ele mesmo:fonte
+1 Zippo, com a exceção de que o corpo da função precisa ser o seguinte ou anexa a cadeia atual a cada iteração:
fonte
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
o resultado se tornaThe ASP is dead. Don't code {0}. Code PHP that is open source!
. Mais uma coisafor(arg in arguments)
não funciona no IE. Eu substituí porfor (arg = 0; arg <arguments.length; arg++)
for...in
não funcionará em todos os navegadores, como este código espera. Ele percorrerá todas as propriedades enumeráveis, que em alguns navegadores incluirãoarguments.length
e em outros nem sequer incluirão os próprios argumentos. De qualquer forma, seObject.prototype
for adicionado a, quaisquer acréscimos provavelmente serão incluídos no grupo. O código deve estar usando umfor
loop padrão , e nãofor...in
.Quero compartilhar minha solução para o 'problema'. Não reinventei a roda, mas tente encontrar uma solução com base no que o JavaScript já faz. A vantagem é que você recebe todas as conversões implícitas gratuitamente. Definir a propriedade prototype $ de String fornece uma sintaxe muito agradável e compacta (veja exemplos abaixo). Talvez não seja a maneira mais eficiente, mas na maioria dos casos, lidando com a saída, ela não precisa ser super otimizada.
Aqui estão alguns exemplos:
fonte
Vou adicionar minhas próprias descobertas que encontrei desde que perguntei:
Infelizmente, parece que o sprintf não lida com a formatação de mil separadores, como o formato de string do .NET.
fonte
Eu uso uma pequena biblioteca chamada String.format para JavaScript, que suporta a maioria dos recursos de seqüência de caracteres de formato (incluindo formato de números e datas) e usa a sintaxe do .NET. O script em si é menor que 4 kB, portanto, não cria muita sobrecarga.
fonte
Muito elegante:
O crédito vai para
(link quebrado)https://gist.github.com/0i0/1519811fonte
{{0}}
, bem como coisas assim{0}{1}.format("{1}", "{0}")
. Deve estar no topo!Se você deseja manipular o separador de milhares, realmente deve usar toLocaleString () do número JavaScript classe pois ele formatará a string da região do usuário.
A classe JavaScript Date pode formatar datas e horas localizadas.
fonte
O projeto PHPJS escreveu implementações JavaScript para muitas das funções do PHP. Como a
sprintf()
função do PHP é basicamente a mesma que a do Cprintf()
, sua implementação em JavaScript deve satisfazer suas necessidades.fonte
Eu uso este:
Então eu chamo:
fonte
Eu tenho uma solução muito próxima da de Peter, mas lida com número e caso de objeto.
Talvez possa ser ainda melhor lidar com todos os casos de aprofundamento, mas, para as minhas necessidades, está tudo bem.
PS: Essa função é muito legal se você estiver usando traduções em estruturas de modelos como o AngularJS :
Onde o en.json é algo como
fonte
Uma versão muito ligeiramente diferente, a que eu prefiro (essa usa tokens {xxx} em vez de {0} argumentos numerados, isso é muito mais documentado e se adapta muito melhor à localização):
Uma variação seria:
que chama uma função de localização l () primeiro.
fonte
Há "sprintf" para JavaScript, que você pode encontrar em http://www.webtoolkit.info/javascript-sprintf.html .
fonte
Para quem gosta do Node.JS e de seu
util.format
recurso, acabei de extraí-lo para o seu formato vanilla JavaScript (com apenas funções que o util.format usa):Colhido em: https://github.com/joyent/node/blob/master/lib/util.js
fonte
Para formatação básica:
fonte
Eu tenho um formatador um pouco mais longo para JavaScript aqui ...
Você pode formatar várias maneiras:
String.format(input, args0, arg1, ...)
String.format(input, obj)
"literal".format(arg0, arg1, ...)
"literal".format(obj)
Além disso, se você disser um ObjectBase.prototype.format (como no DateJS ), ele será usado.
Exemplos...
Eu também fiz um alias com .asFormat e tenho alguma detecção em vigor, caso já exista um string.format (como no MS Ajax Toolkit (eu odeio essa biblioteca).
fonte
Caso alguém precise de uma função para evitar poluir o escopo global, aqui está a função que faz o mesmo:
fonte
Podemos usar uma biblioteca de operações de string String.Format simples e leve para Typescript.
String.Format ():
Formato da string para especificadores:
Formato de string para objetos, incluindo especificadores:
fonte
Eu não vi a
String.format
variante:fonte
Para uso com as funções de sucesso jQuery.ajax (). Passe apenas um único argumento e sequência de caracteres substituídos pelas propriedades desse objeto como {propertyName}:
Exemplo:
fonte